@makefully/adaptfully 4.2.0 → 4.2.2

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/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## 4.2.2 — 2026-09-10
6
+
7
+ ### Added
8
+
9
+ - While a Wrapfully Yap chore is pending, poll `GET /yap/wrapfully/:choreId/logs` and print new live worker log lines.
10
+
11
+ ## 4.2.1 — 2026-09-09
12
+
13
+ ### Fixed
14
+
15
+ - Yap status poll logs only when the status message changes (same as Dutifully), instead of repeating every poll interval.
16
+ - Clearer errors when a chore download/decrypt/unpack fails (helps diagnose truncated Showfully responses).
17
+
5
18
  ## 4.2.0 — 2026-09-08
6
19
 
7
20
  ### Changed
@@ -109,6 +109,9 @@ export async function submitWrapfullyChore ({
109
109
 
110
110
  log(`adaptfully: chore ${choreId} submitted; waiting…`);
111
111
 
112
+ let lastStatus = '';
113
+ let logAfter = 0;
114
+
112
115
  for (;;) {
113
116
  const statusUrl = `${base}yap/wrapfully/${encodeURIComponent(choreId)}/status`;
114
117
  const {data: status} = await axios.get(statusUrl, {
@@ -123,7 +126,34 @@ export async function submitWrapfullyChore ({
123
126
  throw new Error(status.errors?.[0] || `Chore ${choreId} failed`);
124
127
  }
125
128
 
126
- log(`adaptfully: ${status?.status || status?.state || 'waiting'}…`);
129
+ if (status?.state === 'pending') {
130
+ try {
131
+ const logsUrl = `${base}yap/wrapfully/${encodeURIComponent(choreId)}/logs?after=${logAfter}`;
132
+ const {data: logs} = await axios.get(logsUrl, {
133
+ headers: {Authorization: `Bearer ${accessToken}`},
134
+ validateStatus: () => true,
135
+ });
136
+
137
+ if (Array.isArray(logs?.lines) && logs.lines.length) {
138
+ for (const line of logs.lines) {
139
+ const text = line?.message || JSON.stringify(line);
140
+
141
+ log(`adaptfully: ${text}`);
142
+ }
143
+ logAfter = logs.after ?? logAfter;
144
+ lastStatus = '';
145
+ }
146
+ } catch (e) {
147
+ // live logs are best-effort
148
+ }
149
+ }
150
+
151
+ const message = String(status?.status || status?.state || 'waiting');
152
+
153
+ if (message !== lastStatus) {
154
+ log(`adaptfully: ${message}…`);
155
+ lastStatus = message;
156
+ }
127
157
  await sleep(POLL_MS);
128
158
  }
129
159
 
@@ -293,14 +323,29 @@ export async function send (
293
323
  });
294
324
 
295
325
  if (resultPriv) {
296
- resultBuffer = await decryptResultEnvelope(resultBuffer, resultPriv);
326
+ try {
327
+ resultBuffer = await decryptResultEnvelope(resultBuffer, resultPriv);
328
+ } catch (err) {
329
+ throw new Error(`Failed to decrypt Wrapfully result envelope: ${err.message || err}`);
330
+ }
331
+ }
332
+
333
+ if (!Buffer.isBuffer(resultBuffer) || resultBuffer.length < 4
334
+ || resultBuffer[0] !== 0x50 || resultBuffer[1] !== 0x4b) {
335
+ throw new Error('Chore download is not a valid zip (truncated or corrupt response)');
297
336
  }
298
337
 
299
338
  const destination = mode === 'extract'
300
339
  ? unzipper.Extract({path: `${outputRoot}/`, concurrency: 1})
301
340
  : fs.createWriteStream(`${outputRoot}/${pkg.name}-${pkg.version}-${stage}-${family}.zip`);
302
341
 
303
- await pipeline(Readable.from(resultBuffer), destination);
342
+ try {
343
+ await pipeline(Readable.from(resultBuffer), destination);
344
+ } catch (err) {
345
+ throw new Error(
346
+ `Failed to unpack chore result (${resultBuffer.length} bytes): ${err.message || err}`
347
+ );
348
+ }
304
349
 
305
350
  if (mode === 'extract') {
306
351
  printBuildReport(`${stage}-${family}`, pkg);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makefully/adaptfully",
3
- "version": "4.2.0",
3
+ "version": "4.2.2",
4
4
  "description": "Platform abstraction and Wrapfully deploy client for Makefully games",
5
5
  "type": "module",
6
6
  "main": "./lib/node/index.js",