@topy-ai/maggie 0.7.58 → 0.7.59
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/README-zh-TW.md +1 -1
- package/README.md +8 -3
- package/bundled-tools/clis/maggie_security_host.py +34 -8
- package/package.json +1 -1
package/README-zh-TW.md
CHANGED
|
@@ -143,7 +143,7 @@ structure drift 或重複 treatment product 時 fail closed。
|
|
|
143
143
|
deployment、memory、feedback 和 MaggieDash。內容先 draft/review,外部寫入、
|
|
144
144
|
publish 與 production deployment 需要明確確認。
|
|
145
145
|
|
|
146
|
-
目前 npm 版本為 `0.7.
|
|
146
|
+
目前 npm 版本為 `0.7.59`,包含 fix-plan、public-check、Maggie Security、batch 31 排程 agent routines、報告收件匣與無人值守 agent 限制、PHP runtime 盤點與主機鎖、pull 網站改寫、query 點子與社群佇列檢查,batch 30 MaggieDash 先裝核心、release privacy gate、feedback 備援、社群連結與圖片檢查、大量頁面產生與 app 檢查,batch 29 預約規則、部署、app QA、助理與社群功能,以及 batch 28 產品 app、assistant tools、mobile、product release、skills catalog 與 bridge host 功能、batch 26、27 feedback 修正與 idempotent `maggie update`與 Booking email-template 合約/CLI validator 同步。本版完成 2026-09-24 booking feedback batch:Calendar grid/free-slot entry 與 host modal focus-restoration evidence。本版新增 Starter marketplace provisioning plan;本版完成 feedback batches 22、23:加入 declarative browser interaction evidence、design markup/style/content-key gate、compiler source anchoring、entity double-escape protection、`update --help` read-only、noindex hypothetical indexability、可過期 baseline acknowledgement、DOM-only link extraction regression,以及 MaggieDash 0.2.10 的 content override、短期 browser session、CDN-safe public-session cache contracts。authentication 和 isolated dev server 仍由 host 負責。`maggie-booking` workflow、傳統 email/password、Stripe、Resend、public booking flow 及既有安全邊界維持不變;provider-bound video generation 與 transactional delivery 仍記錄在 issue #39,前一批延後功能仍在 issue #38,不會直接成為 active memory。0.7.33 記錄並審查一筆更正回饋;確認 0.7.32 已正確處理 batch index,沒有修改已驗證的 shared behavior。0.7.32 加入 feedback 一基索引支援、MaggieDash panel 的 source/freshness/error evidence、Consent Mode 與實際 write/no-op reconciliation、SEO baseline recapture、sitemap origin rebasing、content-diff scope、migration ledger reconciliation、deployment credential preflight、release provenance/runtime preflight、icon release gate、opt-in blog auto-publish gate,以及 least-privilege VPS deployer。也修復 top-level `maggie feedback` dispatcher parity。0.7.31 加入 update 差異摘要、atomic installer copy、subset install manifest merge,以及 inventory drift 時 doctor non-zero。0.7.30 補上 feedback tracking issue closeout gate 與 batch 14/15 audit ledger。0.7.29 修正 npm package landing page 使用英文 README;0.7.28 加入 versioned Gemini model policy、明確 fallback 與 provenance、bundled-first CLI
|
|
147
147
|
dispatch、`maggie --version`、feedback batch review 聚合與重複偵測、marketplace enrichment evidence、booking
|
|
148
148
|
worker/resolver evidence,以及 read-only migration preflight。它也包含 host-owned mobile app surface contract、signed-in
|
|
149
149
|
camera-state QA、直接 Astro route resolution、correlated feedback batch,以及
|
package/README.md
CHANGED
|
@@ -89,7 +89,12 @@ Maggie keeps the existing project foundation and asks for decisions before
|
|
|
89
89
|
shared routes, analytics, or publishing boundaries change. The current
|
|
90
90
|
package ships 23 installable skills and a local-first MaggieDash foundation.
|
|
91
91
|
|
|
92
|
-
This package is `0.7.
|
|
92
|
+
This package is `0.7.59`. It makes `maggie security host-audit` (the deep
|
|
93
|
+
lynis audit over SSH) robust on hosts where a storage test can stall: lynis runs
|
|
94
|
+
in its own process group under a watchdog, and the bundled profile skips the ZFS
|
|
95
|
+
storage/filesystem tests that hang, so the audit completes instead of timing out.
|
|
96
|
+
|
|
97
|
+
The 0.7.58 release added `maggie security fix-plan` — a
|
|
93
98
|
reviewed remediation runbook built from the open findings (file permissions,
|
|
94
99
|
firewall, package/apt updates, intrusion prevention, web-server config, end of
|
|
95
100
|
life). It writes a shell script you run yourself, under a host lock, after a
|
|
@@ -851,8 +856,8 @@ artifact schemas.
|
|
|
851
856
|
Recommended upgrade sequence for the current release:
|
|
852
857
|
|
|
853
858
|
```bash
|
|
854
|
-
npx @topy-ai/maggie@0.7.
|
|
855
|
-
npx @topy-ai/maggie@0.7.
|
|
859
|
+
npx @topy-ai/maggie@0.7.59 update --scope project --project . --force
|
|
860
|
+
npx @topy-ai/maggie@0.7.59 cleanup --scope project --project .
|
|
856
861
|
```
|
|
857
862
|
|
|
858
863
|
Maintainers should pass npm credentials through the repository helper, never
|
|
@@ -266,18 +266,38 @@ def lynis_findings(ctx: core.Context, data: dict, host: str) -> list[dict]:
|
|
|
266
266
|
|
|
267
267
|
|
|
268
268
|
LYNIS_PROFILE = """# Maggie lynis profile: no upload, skip tests that do not apply to web servers
|
|
269
|
+
# and skip the storage/filesystem enumeration that hangs on ZFS hosts
|
|
270
|
+
# (the remote watchdog below is the backstop if anything else stalls).
|
|
269
271
|
upload=no
|
|
270
272
|
skip-test=PRNT-2307
|
|
271
273
|
skip-test=PRNT-2308
|
|
272
274
|
skip-test=STRG-1840
|
|
273
275
|
skip-test=STRG-1842
|
|
276
|
+
skip-test=STRG-1846
|
|
277
|
+
skip-test=STRG-1902
|
|
274
278
|
skip-test=NAME-4402
|
|
275
279
|
skip-test=NAME-4404
|
|
276
280
|
skip-test=KRB-5108
|
|
277
281
|
skip-test=LDAP-2219
|
|
278
|
-
skip-test=
|
|
282
|
+
skip-test=FILE-6310
|
|
283
|
+
skip-test=FILE-6311
|
|
284
|
+
skip-test=FILE-6329
|
|
285
|
+
skip-test=FILE-6330
|
|
286
|
+
skip-test=FILE-6332
|
|
287
|
+
skip-test=FILE-6336
|
|
288
|
+
skip-test=FILE-6354
|
|
289
|
+
skip-test=FILE-6362
|
|
290
|
+
skip-test=FILE-6368
|
|
291
|
+
skip-test=FILE-6374
|
|
292
|
+
skip-test=FILE-6376
|
|
279
293
|
"""
|
|
280
294
|
|
|
295
|
+
# A ZFS host can wedge a lynis storage test for a very long time, and killing the
|
|
296
|
+
# ssh client leaves the stuck test running and holding the channel. So we run
|
|
297
|
+
# lynis in its own process group under a remote watchdog that SIGKILLs the whole
|
|
298
|
+
# group; the command always returns and flushes, finished or not.
|
|
299
|
+
LYNIS_WATCHDOG_SECONDS = 600
|
|
300
|
+
|
|
281
301
|
|
|
282
302
|
def host_audit(ctx: core.Context):
|
|
283
303
|
args = ctx.args
|
|
@@ -329,15 +349,21 @@ def remote_lynis(ctx: core.Context, alias: str, target: str) -> dict:
|
|
|
329
349
|
subprocess.run(["ssh", "-o", "BatchMode=yes", target, f"umask 077 && mkdir -p {remote_dir}"], check=True, timeout=60)
|
|
330
350
|
subprocess.run(["scp", "-q", "-o", "BatchMode=yes", str(tarball), f"{target}:{remote_dir}/lynis.tar.gz"], check=True, timeout=300)
|
|
331
351
|
profile = shlex.quote(LYNIS_PROFILE)
|
|
332
|
-
# Run lynis with sudo when available (a full audit needs root)
|
|
333
|
-
#
|
|
334
|
-
#
|
|
352
|
+
# Run lynis with sudo when available (a full audit needs root). Run it in
|
|
353
|
+
# its own session (setsid) under a watchdog that SIGKILLs the whole process
|
|
354
|
+
# group if it overruns, so a stuck storage test cannot hang the session or
|
|
355
|
+
# leave an orphan holding the ssh channel. Read report.dat back with the
|
|
356
|
+
# same sudo (a root run writes it 0600, so a plain cat reads nothing).
|
|
357
|
+
inner = (f"setsid ./lynis audit system --quick --no-colors --no-log "
|
|
358
|
+
f"--profile {remote_dir}/maggie.prf --report-file {remote_dir}/report.dat --logfile /dev/null >/dev/null 2>&1 & "
|
|
359
|
+
f"LP=$!; ( sleep {LYNIS_WATCHDOG_SECONDS}; kill -9 -$LP 2>/dev/null ) & WD=$!; "
|
|
360
|
+
f"wait $LP 2>/dev/null; kill $WD 2>/dev/null")
|
|
335
361
|
script = (f"SUDO=$( [ $(id -u) != 0 ] && sudo -n true 2>/dev/null && echo 'sudo -n' ); "
|
|
336
362
|
f"cd {remote_dir} && tar xzf lynis.tar.gz && printf %s {profile} > maggie.prf && cd lynis && "
|
|
337
|
-
f"$SUDO
|
|
338
|
-
f"
|
|
339
|
-
|
|
340
|
-
|
|
363
|
+
f"$SUDO sh -c {shlex.quote(inner)} </dev/null >/dev/null 2>&1; "
|
|
364
|
+
f"$SUDO cat {remote_dir}/report.dat 2>/dev/null")
|
|
365
|
+
proc = subprocess.run(["ssh", "-o", "BatchMode=yes", target, script], input="", capture_output=True, text=True,
|
|
366
|
+
timeout=LYNIS_WATCHDOG_SECONDS + 180, check=False)
|
|
341
367
|
report = proc.stdout
|
|
342
368
|
finally:
|
|
343
369
|
subprocess.run(["ssh", "-o", "BatchMode=yes", target, f"rm -rf {remote_dir}"], timeout=60, check=False)
|