@maka/maka-cli 5.14.0 → 5.15.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/command.js +1 -1
- package/bundle/typescript/src/commands/build/build.js +1 -1
- package/bundle/typescript/src/commands/debug.js +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/call.js +20 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/call.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +21 -0
- package/bundle/typescript/src/commands/game/sideQuest/game.js +90 -1
- package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/headless.d.ts +5 -0
- package/bundle/typescript/src/commands/game/sideQuest/headless.js +4 -1
- package/bundle/typescript/src/commands/game/sideQuest/headless.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js +24 -5
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/shared-run.d.ts +120 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/shared-run.js +424 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/shared-run.js.map +1 -0
- package/bundle/typescript/src/commands/get/global.sub.cmd.js +1 -1
- package/bundle/typescript/src/commands/murder.js +1 -1
- package/bundle/typescript/src/commands/remote/reconfig.sub.cmd.js +1 -1
- package/bundle/typescript/src/commands/set/global.sub.cmd.js +1 -1
- package/bundle/typescript/src/commands/ssl.js +1 -1
- package/bundle/typescript/src/commands/testCmd/mocha.sub.cmd.js +1 -1
- package/bundle/typescript/src/commands/version/version.js +1 -1
- package/bundle/typescript/src/tools/mpi/mpi.class.js +18 -13
- package/bundle/typescript/src/tools/mpi/mpi.class.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE THIN CLIENT (Phase C M4): shared runs live on maka-cli.com -- the
|
|
3
|
+
* server runs the engine, this module is the CLI's side of the wire.
|
|
4
|
+
* Everything rides @maka/meteor-sdk's DDP client (standing transport
|
|
5
|
+
* ruling): one connection per process, opened lazily at the hub, login
|
|
6
|
+
* by the same resume token cloud-saves stores. Every path degrades to a
|
|
7
|
+
* silent no-op when logged out, offline, or killed via MAKA_NO_DDP=1
|
|
8
|
+
* (harnesses) -- solo play must never notice this file exists.
|
|
9
|
+
*
|
|
10
|
+
* Three surfaces:
|
|
11
|
+
* - HubLink: the hub-side connection -- resume login, the invites
|
|
12
|
+
* subscription ("your commlink buzzes"), and method calls.
|
|
13
|
+
* - tryCreateSharedSession: the Krow-call upgrade -- ghost crew slots
|
|
14
|
+
* whose owners are ON the street right now become a real party, and
|
|
15
|
+
* the job drafts on the server (the seed never comes down).
|
|
16
|
+
* - SharedRunSession: session mode -- events stream into the blessed
|
|
17
|
+
* panes, typed input becomes sideQuest.command, death and settlement
|
|
18
|
+
* close the loop.
|
|
19
|
+
*/
|
|
20
|
+
import { createRequire } from 'node:module';
|
|
21
|
+
import { Logger } from './logger.js';
|
|
22
|
+
import { authToken, fetchSave } from './cloud-saves.js';
|
|
23
|
+
import { saveSlug, restorePlayer, writeSaveAtomic } from './persistence.js';
|
|
24
|
+
const require = createRequire(import.meta.url);
|
|
25
|
+
const DEV = process.env.MAKA_DEV === 'True';
|
|
26
|
+
const BASE_URL = DEV
|
|
27
|
+
? `http://localhost:${process.env.MAKA_DEV_PORT ?? 3000}`
|
|
28
|
+
: 'https://www.maka-cli.com';
|
|
29
|
+
function killed() {
|
|
30
|
+
return process.env.MAKA_NO_DDP === '1';
|
|
31
|
+
}
|
|
32
|
+
/** This build IS the engine the server runs -- the version gate compares
|
|
33
|
+
* our own package version against the server's pin. */
|
|
34
|
+
export function engineVersion() {
|
|
35
|
+
for (const rel of ['../../../../../package.json', '../../../../../../package.json']) {
|
|
36
|
+
try {
|
|
37
|
+
const pkg = require(rel);
|
|
38
|
+
if (pkg?.name === '@maka/maka-cli')
|
|
39
|
+
return pkg.version;
|
|
40
|
+
}
|
|
41
|
+
catch { /* try the next depth (src vs bundle layouts) */ }
|
|
42
|
+
}
|
|
43
|
+
return '0.0.0-unknown';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The one DDP connection this process holds. Opened in the background
|
|
47
|
+
* the first time the hub asks for it; the SDK's own retry machinery
|
|
48
|
+
* (backoff, re-subscribe, in-flight re-send) owns reconnects after that.
|
|
49
|
+
*/
|
|
50
|
+
class HubLinkImpl {
|
|
51
|
+
conn;
|
|
52
|
+
connecting;
|
|
53
|
+
userId;
|
|
54
|
+
/** Session docs from the invites subscription, by id. */
|
|
55
|
+
sessions = new Map();
|
|
56
|
+
announced = new Set();
|
|
57
|
+
noticeShown = false;
|
|
58
|
+
/** Fire-and-forget warm-up from the hub -- never blocks a turn. */
|
|
59
|
+
ensure(game) {
|
|
60
|
+
if (killed() || this.conn || this.connecting)
|
|
61
|
+
return;
|
|
62
|
+
if (!authToken())
|
|
63
|
+
return;
|
|
64
|
+
void this.ready(game).catch(() => undefined);
|
|
65
|
+
}
|
|
66
|
+
/** The connection, established if needed. Undefined = offline/logged
|
|
67
|
+
* out (callers degrade); throws only never. */
|
|
68
|
+
async ready(game) {
|
|
69
|
+
if (killed())
|
|
70
|
+
return undefined;
|
|
71
|
+
if (this.conn)
|
|
72
|
+
return this.conn;
|
|
73
|
+
if (this.connecting)
|
|
74
|
+
return this.connecting;
|
|
75
|
+
const token = authToken();
|
|
76
|
+
if (!token)
|
|
77
|
+
return undefined;
|
|
78
|
+
this.connecting = (async () => {
|
|
79
|
+
try {
|
|
80
|
+
const sdk = require('@maka/meteor-sdk');
|
|
81
|
+
await sdk.init({ release: 'METEOR@3.5.1' });
|
|
82
|
+
const conn = await sdk.connectDdp(BASE_URL, { firstConnectTimeoutMs: 15000 });
|
|
83
|
+
const login = (await conn.call('login', { resume: token }));
|
|
84
|
+
this.userId = login?.id;
|
|
85
|
+
this.tapSessions(conn, game);
|
|
86
|
+
await conn.subscribe('sideQuest.invites');
|
|
87
|
+
this.conn = conn;
|
|
88
|
+
return conn;
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
Logger.getInstance().write(`shared-run: hub link unavailable (${err?.message}).`);
|
|
92
|
+
if (!this.noticeShown && game) {
|
|
93
|
+
this.noticeShown = true;
|
|
94
|
+
// One notice, then silence -- the hub works fully offline.
|
|
95
|
+
Logger.getInstance().write(`shared-run: run invites offline this session.`);
|
|
96
|
+
}
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
this.connecting = undefined;
|
|
101
|
+
}
|
|
102
|
+
})();
|
|
103
|
+
return this.connecting;
|
|
104
|
+
}
|
|
105
|
+
/** Every GameRunSessions doc the server publishes to us, kept fresh
|
|
106
|
+
* from the raw DDP stream (added/changed/removed). */
|
|
107
|
+
tapSessions(conn, game) {
|
|
108
|
+
conn.raw._stream.on('message', (raw) => {
|
|
109
|
+
try {
|
|
110
|
+
const m = JSON.parse(raw);
|
|
111
|
+
if (m.collection !== 'GameRunSessions')
|
|
112
|
+
return;
|
|
113
|
+
if (m.msg === 'added') {
|
|
114
|
+
this.sessions.set(m.id, { ...(m.fields ?? {}) });
|
|
115
|
+
}
|
|
116
|
+
else if (m.msg === 'changed') {
|
|
117
|
+
const doc = this.sessions.get(m.id) ?? {};
|
|
118
|
+
Object.assign(doc, m.fields ?? {});
|
|
119
|
+
for (const c of m.cleared ?? [])
|
|
120
|
+
delete doc[c];
|
|
121
|
+
this.sessions.set(m.id, doc);
|
|
122
|
+
}
|
|
123
|
+
else if (m.msg === 'removed') {
|
|
124
|
+
this.sessions.delete(m.id);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (game)
|
|
128
|
+
this.maybeAnnounce(game);
|
|
129
|
+
}
|
|
130
|
+
catch { /* not json / not ours */ }
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/** "Your commlink buzzes" -- once per session, when an invite goes
|
|
134
|
+
* live (status open and we're still 'invited'). */
|
|
135
|
+
maybeAnnounce(game) {
|
|
136
|
+
for (const [id, doc] of this.sessions) {
|
|
137
|
+
if (doc.status !== 'open' || this.announced.has(id))
|
|
138
|
+
continue;
|
|
139
|
+
const me = doc.party?.find(p => p.userID === this.userId);
|
|
140
|
+
if (me?.status !== 'invited')
|
|
141
|
+
continue;
|
|
142
|
+
this.announced.add(id);
|
|
143
|
+
const leader = doc.party?.find(p => p.role === 'leader');
|
|
144
|
+
Logger.getInstance().logWithColor(`📳 Your commlink buzzes -- ${leader?.actorName ?? 'a runner'} has a live job for the crew: "${doc.pitch ?? 'a run'}". ("call taxi" to ride.)`, 'green');
|
|
145
|
+
game.updateStatus();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/** The freshest OPEN session we're invited to (or reconnecting to). */
|
|
149
|
+
openInvite() {
|
|
150
|
+
for (const [id, doc] of this.sessions) {
|
|
151
|
+
if (doc.status !== 'open')
|
|
152
|
+
continue;
|
|
153
|
+
const me = doc.party?.find(p => p.userID === this.userId);
|
|
154
|
+
if (me && (me.status === 'invited' || me.status === 'disconnected' || me.status === 'joined')) {
|
|
155
|
+
return { sessionID: id, pitch: doc.pitch };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
async call(name, params) {
|
|
161
|
+
const conn = await this.ready();
|
|
162
|
+
if (!conn)
|
|
163
|
+
throw new Error('offline');
|
|
164
|
+
return conn.call(name, params);
|
|
165
|
+
}
|
|
166
|
+
/** Scrap a server-side draft (party changed / decline). Silent. */
|
|
167
|
+
abortDraft(sessionID) {
|
|
168
|
+
void this.call('sideQuest.abortDraft', { sessionID }).catch(() => undefined);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
export const HubLink = new HubLinkImpl();
|
|
172
|
+
/** Hub warm-up hook (Game.initEngine): connect + invites, in the
|
|
173
|
+
* background. */
|
|
174
|
+
export function ensureHubLink(game) {
|
|
175
|
+
HubLink.ensure(game);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Ghost crew slots whose owners are on the street right now become a
|
|
179
|
+
* REAL party: the job drafts on the server. Returns undefined when the
|
|
180
|
+
* shared path doesn't apply (no ghost crew, logged out, offline, or the
|
|
181
|
+
* server declines -- e.g. an owner just went dark); the caller falls
|
|
182
|
+
* back to the local draft with the ghosts as AI riders (Phase B).
|
|
183
|
+
*/
|
|
184
|
+
export async function tryCreateSharedSession(game) {
|
|
185
|
+
if (killed())
|
|
186
|
+
return undefined;
|
|
187
|
+
const ghosts = game.crew.filter(m => m.source === 'ghost' && m.ghost);
|
|
188
|
+
if (ghosts.length === 0)
|
|
189
|
+
return undefined;
|
|
190
|
+
if (!authToken())
|
|
191
|
+
return undefined;
|
|
192
|
+
try {
|
|
193
|
+
const res = await HubLink.call('sideQuest.createSession', {
|
|
194
|
+
engineVersion: engineVersion(),
|
|
195
|
+
slug: saveSlug(game.player.name),
|
|
196
|
+
party: ghosts.map(g => ({ handle: g.ghost.owner, slug: g.ghost.slug })),
|
|
197
|
+
});
|
|
198
|
+
return res;
|
|
199
|
+
}
|
|
200
|
+
catch (err) {
|
|
201
|
+
const e = err;
|
|
202
|
+
Logger.getInstance().write(`shared-run: server draft declined (${e.error ?? ''} ${e.reason ?? e.message ?? ''}) -- falling back to local ghosts.`);
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* A live shared run, from this terminal's side: the server's event
|
|
208
|
+
* stream renders into the same blessed panes solo play uses, and every
|
|
209
|
+
* typed command ships to sideQuest.command. Installed as
|
|
210
|
+
* game.remoteSession -- Game.handleInput delegates here wholesale, so
|
|
211
|
+
* ui.ts needs no new wiring.
|
|
212
|
+
*/
|
|
213
|
+
export class SharedRunSession {
|
|
214
|
+
game;
|
|
215
|
+
sessionID;
|
|
216
|
+
lastSeq = 0;
|
|
217
|
+
dead = false;
|
|
218
|
+
over = false;
|
|
219
|
+
quitArmed = false;
|
|
220
|
+
subs = [];
|
|
221
|
+
constructor(game, sessionID) {
|
|
222
|
+
this.game = game;
|
|
223
|
+
this.sessionID = sessionID;
|
|
224
|
+
}
|
|
225
|
+
static async startAsLeader(game, sessionID) {
|
|
226
|
+
await HubLink.call('sideQuest.start', { sessionID, engineVersion: engineVersion() });
|
|
227
|
+
return SharedRunSession.enter(game, sessionID);
|
|
228
|
+
}
|
|
229
|
+
static async joinAsMember(game, sessionID) {
|
|
230
|
+
await HubLink.call('sideQuest.join', { sessionID, engineVersion: engineVersion() });
|
|
231
|
+
return SharedRunSession.enter(game, sessionID);
|
|
232
|
+
}
|
|
233
|
+
static async enter(game, sessionID) {
|
|
234
|
+
const s = new SharedRunSession(game, sessionID);
|
|
235
|
+
await s.subscribe();
|
|
236
|
+
game.remoteSession = s;
|
|
237
|
+
return `The cab hums through streets you don't know yet. Somewhere across the sprawl, the rest of the crew is riding too.\n{cyan-fg}▣ SHARED RUN -- the table is live. Everything you do happens for everyone.{/cyan-fg}`;
|
|
238
|
+
}
|
|
239
|
+
async subscribe() {
|
|
240
|
+
const conn = await HubLink.ready();
|
|
241
|
+
if (!conn)
|
|
242
|
+
throw new Error('offline');
|
|
243
|
+
conn.raw._stream.on('message', (raw) => {
|
|
244
|
+
try {
|
|
245
|
+
const m = JSON.parse(raw);
|
|
246
|
+
if (m.msg === 'added' && m.collection === 'GameSessionEvents' && m.fields?.sessionID === this.sessionID) {
|
|
247
|
+
this.route(m.fields);
|
|
248
|
+
}
|
|
249
|
+
if (m.msg === 'changed' && m.collection === 'GameRunSessions' && m.id === this.sessionID) {
|
|
250
|
+
const status = m.fields?.status;
|
|
251
|
+
if (status === 'interrupted' && !this.over) {
|
|
252
|
+
this.finish(`{yellow-fg}The run dissolves into static -- the link to the table is gone. Everyone keeps their last save.{/yellow-fg}`);
|
|
253
|
+
}
|
|
254
|
+
if (status === 'settled' && !this.over) {
|
|
255
|
+
// The leader settled the table (or the street did) -- ride home.
|
|
256
|
+
void this.homecoming();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
catch { /* not ours */ }
|
|
261
|
+
});
|
|
262
|
+
this.subs.push(await conn.subscribe('sideQuest.session', this.sessionID));
|
|
263
|
+
this.subs.push(await conn.subscribe('sideQuest.events', this.sessionID, 0));
|
|
264
|
+
}
|
|
265
|
+
/** One server event into the panes. seq-deduped: the SDK re-subscribes
|
|
266
|
+
* from 0 after a reconnect and replays what we've already drawn. */
|
|
267
|
+
route(ev) {
|
|
268
|
+
if (ev.seq <= this.lastSeq)
|
|
269
|
+
return;
|
|
270
|
+
this.lastSeq = ev.seq;
|
|
271
|
+
const g = this.game;
|
|
272
|
+
switch (ev.channel) {
|
|
273
|
+
case 'log': {
|
|
274
|
+
for (const line of ev.text.split('\n'))
|
|
275
|
+
g.logBox?.pushLine(line);
|
|
276
|
+
g.followLog?.();
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
case 'meta': {
|
|
280
|
+
for (const line of ev.text.split('\n'))
|
|
281
|
+
g.metaBox?.pushLine(line);
|
|
282
|
+
g.metaBox?.scrollTo(g.metaBox.getScrollHeight());
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
case 'status': {
|
|
286
|
+
// The server resolves visibility -- a status event that reaches
|
|
287
|
+
// this subscription is OURS.
|
|
288
|
+
g.statusBox?.setContent(ev.text);
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
case 'system': {
|
|
292
|
+
for (const line of ev.text.split('\n'))
|
|
293
|
+
g.logBox?.pushLine(`{cyan-fg}${line}{/cyan-fg}`);
|
|
294
|
+
g.followLog?.();
|
|
295
|
+
if (ev.kind === 'death' && ev.data?.player === g.player.name) {
|
|
296
|
+
this.dead = true;
|
|
297
|
+
// Full permadeath (ruling 4): the server already burned the
|
|
298
|
+
// cloud save; close() burns the local one and freezes input --
|
|
299
|
+
// the same one death choke point solo play uses.
|
|
300
|
+
void g.close().then(() => {
|
|
301
|
+
Logger.getInstance().logWithColor(`💀 GAME OVER: ${g.player.name} died on a shared run. The street keeps the change.`, 'red');
|
|
302
|
+
Logger.getInstance().logWithColor(`Press ctrl-c to quit.`, 'red');
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
if (ev.kind === 'settled' && !this.over) {
|
|
306
|
+
void this.homecoming();
|
|
307
|
+
}
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
g.screenRender?.();
|
|
312
|
+
}
|
|
313
|
+
/** Typed input, shipped to the table. Returns what handleInput would. */
|
|
314
|
+
async command(input) {
|
|
315
|
+
if (this.dead) {
|
|
316
|
+
return `You're gone. The street keeps the change. (ctrl-c to quit.)`;
|
|
317
|
+
}
|
|
318
|
+
if (this.over)
|
|
319
|
+
return '';
|
|
320
|
+
const verb = input.trim().split(' ')[0]?.toLowerCase();
|
|
321
|
+
if (this.quitArmed) {
|
|
322
|
+
this.quitArmed = false;
|
|
323
|
+
if (/^(y|yes|quit|exit|leave)$/i.test(verb ?? '')) {
|
|
324
|
+
return this.leave();
|
|
325
|
+
}
|
|
326
|
+
// fall through: the answer was a real command.
|
|
327
|
+
}
|
|
328
|
+
else if (verb === 'quit' || verb === 'exit' || verb === 'leave') {
|
|
329
|
+
this.quitArmed = true;
|
|
330
|
+
return `Walk out on a LIVE run? Your snapshot is kept, your share of the wrap-up is not. ("y" to leave -- anything else keeps playing.)`;
|
|
331
|
+
}
|
|
332
|
+
if (!verb)
|
|
333
|
+
return '';
|
|
334
|
+
// THE RIDE HOME: on a shared run the taxi is the settlement
|
|
335
|
+
// handshake, not an engine verb -- the leader closes the table for
|
|
336
|
+
// everyone (snapshots persist, shares already on each stick); a
|
|
337
|
+
// member's cab is a voluntary extraction (kept snapshot, forfeited
|
|
338
|
+
// wrap-up share).
|
|
339
|
+
if (/^call\s+(a\s+|the\s+)?(taxi|cab)\b/i.test(input.trim())) {
|
|
340
|
+
try {
|
|
341
|
+
await HubLink.call('sideQuest.settle', { sessionID: this.sessionID });
|
|
342
|
+
await this.homecoming();
|
|
343
|
+
return '';
|
|
344
|
+
}
|
|
345
|
+
catch (err) {
|
|
346
|
+
const e = err;
|
|
347
|
+
if (e.error === 'not-leader') {
|
|
348
|
+
return this.leave();
|
|
349
|
+
}
|
|
350
|
+
if (e.error === 'bad-status' || e.error === 'interrupted') {
|
|
351
|
+
await this.homecoming();
|
|
352
|
+
return '';
|
|
353
|
+
}
|
|
354
|
+
return `{yellow-fg}The dispatcher can't find the table -- try again.{/yellow-fg}`;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
try {
|
|
358
|
+
const res = await HubLink.call('sideQuest.command', {
|
|
359
|
+
sessionID: this.sessionID,
|
|
360
|
+
input,
|
|
361
|
+
});
|
|
362
|
+
this.game.lastResolvedVerb = res.verb ?? verb ?? '';
|
|
363
|
+
return res.text;
|
|
364
|
+
}
|
|
365
|
+
catch (err) {
|
|
366
|
+
const e = err;
|
|
367
|
+
if (e.error === 'interrupted' || e.error === 'bad-status') {
|
|
368
|
+
this.finish(`{yellow-fg}${e.reason ?? 'The run is over.'}{/yellow-fg}`);
|
|
369
|
+
return '';
|
|
370
|
+
}
|
|
371
|
+
return `{yellow-fg}The link chokes on that (${e.reason ?? e.message ?? 'no reply'}) -- try again.{/yellow-fg}`;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
/** Voluntary extraction: snapshot written back server-side, wrap-up
|
|
375
|
+
* share forfeited. */
|
|
376
|
+
async leave() {
|
|
377
|
+
try {
|
|
378
|
+
await HubLink.call('sideQuest.leave', { sessionID: this.sessionID });
|
|
379
|
+
}
|
|
380
|
+
catch { /* the server sweep will settle it */ }
|
|
381
|
+
await this.homecoming();
|
|
382
|
+
return `You pull out of the run. The crew's voices fade off the link.`;
|
|
383
|
+
}
|
|
384
|
+
/** The ride home: fresh cloud save (the run's loot, pay, and karma --
|
|
385
|
+
* written back by the server) lands in the live hub player and on
|
|
386
|
+
* disk; the hub Game, which never went anywhere, takes back over. */
|
|
387
|
+
async homecoming() {
|
|
388
|
+
if (this.over)
|
|
389
|
+
return;
|
|
390
|
+
this.finish('');
|
|
391
|
+
const g = this.game;
|
|
392
|
+
const slug = saveSlug(g.player.name);
|
|
393
|
+
try {
|
|
394
|
+
const cloud = await fetchSave(slug);
|
|
395
|
+
if (cloud) {
|
|
396
|
+
restorePlayer(g.player, cloud.player);
|
|
397
|
+
if (g.saveFilePath)
|
|
398
|
+
writeSaveAtomic(g.saveFilePath, cloud);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
catch (err) {
|
|
402
|
+
Logger.getInstance().write(`shared-run: homecoming save pull failed (${err?.message}) -- next cloud sync reconciles.`);
|
|
403
|
+
}
|
|
404
|
+
Logger.getInstance().logWithColor(`\nA cab noses out of the dark and takes you home. The job is settled -- whatever landed on your stick rode home with you.`, 'green');
|
|
405
|
+
g.updateStatus();
|
|
406
|
+
}
|
|
407
|
+
finish(banner) {
|
|
408
|
+
this.over = true;
|
|
409
|
+
this.game.remoteSession = undefined;
|
|
410
|
+
for (const s of this.subs.splice(0)) {
|
|
411
|
+
try {
|
|
412
|
+
s.stop();
|
|
413
|
+
}
|
|
414
|
+
catch { /* already down */ }
|
|
415
|
+
}
|
|
416
|
+
if (banner) {
|
|
417
|
+
for (const line of banner.split('\n'))
|
|
418
|
+
this.game.logBox?.pushLine(line);
|
|
419
|
+
this.game.followLog?.();
|
|
420
|
+
this.game.screenRender?.();
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
//# sourceMappingURL=shared-run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-run.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/utilities/shared-run.ts"],"names":[],"mappings":"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"}
|
|
@@ -358,7 +358,13 @@ export class MPI {
|
|
|
358
358
|
catch {
|
|
359
359
|
Log.error(`This project's version is at ${projectRelease}, however you are using ${systemRelease}.`);
|
|
360
360
|
Log.notice(`Consider updating this project, or installing the version of Meteor using 'maka install meteor --release ${projectRelease}'`);
|
|
361
|
-
|
|
361
|
+
// Exit NONZERO: this is a failure, and callers (especially CI
|
|
362
|
+
// pipelines running `maka build` under `bash -e`) must see it
|
|
363
|
+
// as one. This used to exit 0, which let a real deploy
|
|
364
|
+
// pipeline sail past a build that never produced a bundle --
|
|
365
|
+
// with a stale build/ artifact lying around it would have
|
|
366
|
+
// shipped old code silently.
|
|
367
|
+
process.exit(1);
|
|
362
368
|
}
|
|
363
369
|
}
|
|
364
370
|
Log.notice(`Running: meteor ${runArgs.join(' ')}`);
|
|
@@ -771,19 +777,18 @@ export class MPI {
|
|
|
771
777
|
return String(value);
|
|
772
778
|
}
|
|
773
779
|
};
|
|
774
|
-
sdk.on('log', ({
|
|
780
|
+
sdk.on('log', ({ args }) => {
|
|
775
781
|
const line = args.map((a) => (typeof a === 'string' ? a : safeStringify(a))).join(' ');
|
|
776
|
-
//
|
|
777
|
-
//
|
|
778
|
-
//
|
|
779
|
-
//
|
|
780
|
-
//
|
|
781
|
-
//
|
|
782
|
-
//
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
writeLog(line); // log file: with timestamps
|
|
782
|
+
// Log file ONLY -- never the console. The SDK's console tap
|
|
783
|
+
// emits an event for every Console call and then still runs the
|
|
784
|
+
// original method, which already prints every non-debug level to
|
|
785
|
+
// the terminal itself (only debug is suppressed at default
|
|
786
|
+
// verbosity). Printing here too double-printed every app/tool
|
|
787
|
+
// line -- easy to miss because Console's copy is wrapped/
|
|
788
|
+
// prefixed while this raw copy isn't, so the two rarely compared
|
|
789
|
+
// equal; app stderr lines (raw passthrough on both paths) made
|
|
790
|
+
// it visible. The file still gets everything, debug included.
|
|
791
|
+
writeLog(line);
|
|
787
792
|
});
|
|
788
793
|
await handle.start();
|
|
789
794
|
Log.success(`Running: http://localhost:${options.port}`);
|