@symerian/symi 2.6.42 → 2.7.1
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/dist/{acp-cli-CrEIx-c7.js → acp-cli-B2f0qBiM.js} +2 -2
- package/dist/{acp-cli-BLUeUUA5.js → acp-cli-D-9rzaOI.js} +2 -2
- package/dist/{agents-DDRDszOI.js → agents-Z8ruJPz2.js} +5 -5
- package/dist/{agents.config-BEVb1Pyx.js → agents.config-B9BZoM2m.js} +1 -1
- package/dist/{agents.config-BKCY6F2A.js → agents.config-C951ocyh.js} +1 -1
- package/dist/{audio-preflight-DD18zIZd.js → audio-preflight-HILy3i0m.js} +4 -4
- package/dist/{audit-DB9YkTVX.js → audit-BgdM9XZl.js} +2 -2
- package/dist/{audit-BjI_Yyr5.js → audit-xSagQWH8.js} +2 -2
- package/dist/{auth-choice-D2xXwBeN.js → auth-choice-BmYi6pBy.js} +2 -2
- package/dist/{auth-choice-BbzReh6k.js → auth-choice-D_VfXxhG.js} +2 -2
- package/dist/{banner-DqqRwplt.js → banner-Bucr6qZ5.js} +1 -1
- package/dist/{browser-cli-kDUw45Y0.js → browser-cli-Bc_JVdTj.js} +3 -3
- package/dist/{browser-cli-Ctn9do4z.js → browser-cli-Dr0yx7-7.js} +3 -3
- package/dist/build-info.json +3 -3
- package/dist/bundled/boot-md/handler.js +1 -1
- package/dist/bundled/session-memory/handler.js +1 -1
- package/dist/{call-DwpGquzW.js → call-CX0cs106.js} +1 -1
- package/dist/{call-DKi-hnaF.js → call-DeCQ2DhS.js} +1 -1
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/{channel-options-DQcpDVCx.js → channel-options-BMDryXHq.js} +1 -1
- package/dist/{channel-options-DcazVJQf.js → channel-options-z8-WeZyO.js} +1 -1
- package/dist/{channel-web-u5yMYO4j.js → channel-web-D_YxZAHT.js} +1 -1
- package/dist/{channels-cli-C3iJE8eg.js → channels-cli-397NgC51.js} +7 -7
- package/dist/{channels-cli-Bog4Kn3X.js → channels-cli-CV7_JUru.js} +7 -7
- package/dist/{chrome-BxwUEWrH.js → chrome-CiOKaTN-.js} +7 -7
- package/dist/cli/daemon-cli.js +1 -1
- package/dist/{cli-eBtEEHLK.js → cli-4XU7pNlM.js} +4 -4
- package/dist/{cli-QybdZdE7.js → cli-Dq95udFO.js} +4 -4
- package/dist/{client-jI1oE0_k.js → client-B8xmq-Pw.js} +13 -1
- package/dist/{client-T3qcxXru.js → client-qUlxXXVJ.js} +13 -1
- package/dist/{command-registry-BWnZSpbL.js → command-registry-Cx9T7GYx.js} +10 -10
- package/dist/{completion-cli-BhJFXaVU.js → completion-cli-WlSuySPZ.js} +1 -1
- package/dist/{completion-cli-CUKm7Hb6.js → completion-cli-cyVjlhls.js} +2 -2
- package/dist/{config-cli-B796xZBe.js → config-cli-CMymzmrI.js} +1 -1
- package/dist/{config-cli-CjnQyv45.js → config-cli-EdmbBExA.js} +1 -1
- package/dist/{configure-D3wIQ0yI.js → configure-DRMAIBBf.js} +6 -6
- package/dist/{configure-DUqT7Dyn.js → configure-DkFujfiY.js} +6 -6
- package/dist/control-ui/css/style.css +165 -0
- package/dist/control-ui/js/app.js +39 -0
- package/dist/control-ui/js/gateway.js +2 -0
- package/dist/control-ui/js/history.js +220 -85
- package/dist/control-ui/js/settings.js +71 -8
- package/dist/{cron-cli-DCpsXkrw.js → cron-cli-BHxfvWeT.js} +3 -3
- package/dist/{cron-cli-QCTdVZuP.js → cron-cli-DacyI1Pw.js} +3 -3
- package/dist/{daemon-cli-DSDcmWOi.js → daemon-cli-BLhFbih0.js} +2 -2
- package/dist/{daemon-cli-DhJYEAoL.js → daemon-cli-BxKtiouf.js} +2 -2
- package/dist/daemon-cli.js +12 -0
- package/dist/{deliver-DtuY4Wgl.js → deliver-D6IcPfbt.js} +1 -1
- package/dist/{devices-cli-BNG-fvdl.js → devices-cli-1kiO08aL.js} +2 -2
- package/dist/{devices-cli-x3jIP4Ih.js → devices-cli-B8Q8AzbX.js} +2 -2
- package/dist/{doctor-completion-DBE1IVKj.js → doctor-completion-BDzhB9pE.js} +1 -1
- package/dist/{doctor-completion-D3oUNFQM.js → doctor-completion-CfeROjIz.js} +1 -1
- package/dist/entry.js +1 -1
- package/dist/{exec-approvals-cli-CmndFjEA.js → exec-approvals-cli-BRx2oxs5.js} +4 -4
- package/dist/{exec-approvals-cli-BSgxsdMt.js → exec-approvals-cli-Cj6Z-vxL.js} +4 -4
- package/dist/extensionAPI.js +6 -6
- package/dist/{gateway-cli-BguO9yV4.js → gateway-cli-C-G0QrTd.js} +185 -81
- package/dist/{gateway-cli-Dc1RT_b9.js → gateway-cli-Cpn7JyAw.js} +185 -81
- package/dist/{gateway-rpc-BMdVa3QV.js → gateway-rpc-BWTK7g8B.js} +1 -1
- package/dist/{gateway-rpc-5fREQe9Q.js → gateway-rpc-WM-HXUbl.js} +1 -1
- package/dist/{glass-ui-ws-DoIZyE9O.js → glass-ui-ws-BI81Lh6Z.js} +32 -13
- package/dist/{glass-ui-ws-D0UYleBF.js → glass-ui-ws-jAbqZVc9.js} +32 -13
- package/dist/{health-D3w4YMlC.js → health-B1nih5LD.js} +2 -2
- package/dist/{health-cVvZdeDu.js → health-CsTxt66a.js} +2 -2
- package/dist/{hooks-cli-te5hzOAB.js → hooks-cli-BhxMFkKe.js} +5 -5
- package/dist/{hooks-cli-DZIbjfOA.js → hooks-cli-CIlvtt2M.js} +5 -5
- package/dist/{image-lp19FlzF.js → image-D7Fl08gG.js} +1 -1
- package/dist/index.js +9 -9
- package/dist/llm-slug-generator.js +1 -1
- package/dist/{logs-cli-DtlrLf7u.js → logs-cli-BZV7dq_U.js} +3 -3
- package/dist/{logs-cli-CfGj-dOg.js → logs-cli-DyCcDkRs.js} +3 -3
- package/dist/{models-BCfPhQ4m.js → models-DhMe2rzL.js} +3 -3
- package/dist/{models-cli-BFAtjNIF.js → models-cli-DKM5sCQM.js} +5 -5
- package/dist/{models-cli-Cj2CwbPw.js → models-cli-Dewg24W2.js} +6 -6
- package/dist/{node-cli-DnfDOh1d.js → node-cli-4eMRkmrw.js} +1 -1
- package/dist/{node-cli-eHn9-YfJ.js → node-cli-Dfs0UmnJ.js} +1 -1
- package/dist/{nodes-cli-Ct4M7JOe.js → nodes-cli-BKb61OjH.js} +3 -3
- package/dist/{nodes-cli-Ci3oxw8k.js → nodes-cli-DxfP9DIz.js} +3 -3
- package/dist/{onboard-BMq8qc1m.js → onboard-Dw_nX2RD.js} +3 -3
- package/dist/{onboard-channels-B5wgcffj.js → onboard-channels-8ynJSZL6.js} +1 -1
- package/dist/{onboard-channels-CiOun4k1.js → onboard-channels-ChxtmhFY.js} +1 -1
- package/dist/{onboard-helpers-DFvWPFhU.js → onboard-helpers-CueJ7O_B.js} +1 -1
- package/dist/{onboard-helpers-BBtPmJEe.js → onboard-helpers-PpGrZIGw.js} +1 -1
- package/dist/{onboard-remote-BURDxwoE.js → onboard-remote-Cd9kIiSG.js} +1 -1
- package/dist/{onboard-remote-D-B4EiOE.js → onboard-remote-DCdpB2HH.js} +1 -1
- package/dist/{onboard-skills-BDCzVjxb.js → onboard-skills-CC2CV5Er.js} +1 -1
- package/dist/{onboard-skills-CbzgBT1W.js → onboard-skills-DRICcBwa.js} +1 -1
- package/dist/{onboard-VcdBF5TB.js → onboard-yrgbC1mu.js} +3 -3
- package/dist/{onboarding-Dp7p6zKa.js → onboarding-BJcYsOFw.js} +7 -7
- package/dist/{onboarding-CGNpTyg2.js → onboarding-e-RSXpUi.js} +7 -7
- package/dist/{onboarding.finalize-B6DOu8vp.js → onboarding.finalize-CKNdiZEZ.js} +9 -9
- package/dist/{onboarding.finalize-CrsE5P43.js → onboarding.finalize-DenYTWUu.js} +10 -10
- package/dist/{onboarding.gateway-config-DKwJ5bWd.js → onboarding.gateway-config-DTWQ-Bqq.js} +3 -3
- package/dist/{onboarding.gateway-config-B9zGPfCl.js → onboarding.gateway-config-Dj68bVBt.js} +3 -3
- package/dist/{pi-embedded-DQe8vBwU.js → pi-embedded-BzS693I1.js} +72 -21
- package/dist/{pi-embedded-helpers-Dij3O6ox.js → pi-embedded-helpers-DXAoe1Bx.js} +4 -4
- package/dist/{plugin-registry-BzIbwU3K.js → plugin-registry-Bzz7mUyl.js} +1 -1
- package/dist/{plugin-registry-D3TUplW8.js → plugin-registry-SUa2FFIj.js} +1 -1
- package/dist/plugin-sdk/{channel-web-B6m8UOCl.js → channel-web-DRabhx1e.js} +1 -1
- package/dist/plugin-sdk/gateway/protocol/index.d.ts +13 -2
- package/dist/plugin-sdk/gateway/protocol/schema/sessions.d.ts +11 -0
- package/dist/plugin-sdk/gateway/protocol/schema/types.d.ts +4 -1
- package/dist/plugin-sdk/index.js +2 -2
- package/dist/plugin-sdk/{reply-CGoJQT_s.js → reply-Cw3shPk2.js} +58 -7
- package/dist/plugin-sdk/{web-CJjSOTnI.js → web-CH43nBP0.js} +2 -2
- package/dist/{plugins-cli-BD1Jb2Ml.js → plugins-cli-DwtoU3xk.js} +5 -5
- package/dist/{plugins-cli-DFyRjAtJ.js → plugins-cli-qG50__1A.js} +5 -5
- package/dist/{program-context-45vPEw2G.js → program-context-CZwy-bh6.js} +29 -29
- package/dist/{program-qGm2M9PG.js → program-mZOVTSdQ.js} +10 -10
- package/dist/{prompt-select-styled-DRIS9jSv.js → prompt-select-styled-BZnuv8jI.js} +6 -6
- package/dist/{prompt-select-styled-DRraJGwA.js → prompt-select-styled-CtNg5KGU.js} +6 -6
- package/dist/{provider-auth-helpers-BNOWsjW5.js → provider-auth-helpers-CEYCb2mJ.js} +1 -1
- package/dist/{provider-auth-helpers-BREVjR7R.js → provider-auth-helpers-D60nbSLq.js} +1 -1
- package/dist/{push-apns-CYC70eKy.js → push-apns-B5txhDVi.js} +1 -1
- package/dist/{push-apns-CObVeJLC.js → push-apns-CoG1P_P0.js} +1 -1
- package/dist/{pw-ai-BO5cSmwD.js → pw-ai-CANiWpMA.js} +1 -1
- package/dist/{register.agent-DzzY8jON.js → register.agent-BY_Df_Me.js} +9 -9
- package/dist/{register.agent-DRrHvYcz.js → register.agent-CopGIf9e.js} +8 -8
- package/dist/{register.configure-DlXkwkNR.js → register.configure-Bu_XKu7Z.js} +11 -11
- package/dist/{register.configure-BxtTIFTa.js → register.configure-CoYQhQBT.js} +11 -11
- package/dist/{register.maintenance-LEf8Q_5p.js → register.maintenance-BtqQ3hDN.js} +11 -11
- package/dist/{register.maintenance-CXLXouZV.js → register.maintenance-VqCqhB7y.js} +10 -10
- package/dist/{register.message-DsPa-xHV.js → register.message-DZCCEK01.js} +5 -5
- package/dist/{register.message-C4ifV9vG.js → register.message-dd1xYBZT.js} +5 -5
- package/dist/{register.onboard-CrY4PxLP.js → register.onboard-B6EL1d-C.js} +7 -7
- package/dist/{register.onboard-DLRPa_4B.js → register.onboard-lzwHKufI.js} +7 -7
- package/dist/{register.setup-fBG_dJfi.js → register.setup-BJsr5_qp.js} +7 -7
- package/dist/{register.setup-By37g1vN.js → register.setup-D_b_HW5D.js} +7 -7
- package/dist/{register.status-health-sessions-DG7KGnD0.js → register.status-health-sessions-Dvj4mlom.js} +7 -7
- package/dist/{register.status-health-sessions-Ckw86-gn.js → register.status-health-sessions-jeiqtgl7.js} +7 -7
- package/dist/{register.subclis-C_xKLugM.js → register.subclis-DdPRkz29.js} +20 -20
- package/dist/{reply-DyjXROKp.js → reply-XaXqDK9F.js} +49 -10
- package/dist/{rpc-Co5PQ3IJ.js → rpc-N1nf_c1A.js} +1 -1
- package/dist/{rpc-D0FiEinj.js → rpc-QHo-8pCM.js} +1 -1
- package/dist/{run-main-Cg3ecTbO.js → run-main-MhL-xG3_.js} +17 -17
- package/dist/{runner-Ct0suQrd.js → runner-BS9gGL5i.js} +1 -1
- package/dist/{security-cli-D5BWzqEJ.js → security-cli-B-4J6enu.js} +3 -3
- package/dist/{security-cli-CG1uSlRK.js → security-cli-CSMUEGPK.js} +3 -3
- package/dist/{server-methods-CWcLut3F.js → server-methods-0ksPFnev.js} +471 -88
- package/dist/{server-methods-CW8eFTGD.js → server-methods-Bu1RjLe6.js} +471 -88
- package/dist/{server-node-events-C2h9OPo7.js → server-node-events-DCbzFyQF.js} +5 -5
- package/dist/{server-node-events-CDB0u8PP.js → server-node-events-DZAN3hWE.js} +5 -5
- package/dist/{status-B2Qt-5kL.js → status-CiHkFbIh.js} +1 -1
- package/dist/{status-ZPW5EACm.js → status-DOTlXdcN.js} +5 -5
- package/dist/{status-CMx3GAax.js → status-IWqSLXLR.js} +1 -1
- package/dist/{status-DfPfMVNZ.js → status-qkmUAeWo.js} +5 -5
- package/dist/{subagent-registry-DQHg3jUV.js → subagent-registry-DCoU9xIE.js} +49 -10
- package/dist/{system-cli-DFZNGx0i.js → system-cli-DY7ov1OT.js} +3 -3
- package/dist/{system-cli-Z7uzO8qd.js → system-cli-LFURKpwS.js} +3 -3
- package/dist/{tui-DjPsMdL6.js → tui-BH7JwqvB.js} +2 -2
- package/dist/{tui-DrATGNms.js → tui-C_5HG495.js} +2 -2
- package/dist/{tui-cli-D19-MCXt.js → tui-cli-B65PKZMj.js} +3 -3
- package/dist/{tui-cli-pWD_NrUR.js → tui-cli-CJnfmuxq.js} +3 -3
- package/dist/{unified-runner-DvOFqcrw.js → unified-runner-CApgXtVC.js} +58 -7
- package/dist/{update-cli-Df9rh_aN.js → update-cli-Bi6iMCXr.js} +11 -11
- package/dist/{update-cli-DBasZeVl.js → update-cli-BjQ3o9gQ.js} +12 -12
- package/dist/{update-runner-DVa6cMqp.js → update-runner-BhVsdpxm.js} +1 -1
- package/dist/{update-runner-BRKFzAwV.js → update-runner-FhW6n-Nv.js} +1 -1
- package/dist/{web-Dd05xbUr.js → web-ConlA_Ch.js} +4 -4
- package/dist/{web-Cw3bFAiP.js → web-CthDLVSz.js} +1 -1
- package/dist/{web-CGh5tw__.js → web-Db_-ahjX.js} +6 -6
- package/dist/{web-KiuDkd0x.js → web-Dpb_tv_j.js} +5 -5
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/feishu/package.json +1 -1
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/learning-loop/package.json +1 -1
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +12 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +12 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +12 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/outlook/package.json +1 -1
- package/extensions/pipeline/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +12 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +12 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +12 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +12 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
- package/skills/long-task/scripts/detach-task.sh +91 -14
|
@@ -10,18 +10,28 @@
|
|
|
10
10
|
# task-<id>.cmd — literal command line (for future agent turns to see)
|
|
11
11
|
# task-<id>.started — ISO-8601 start timestamp
|
|
12
12
|
# task-<id>.log — combined stdout + stderr (grows as task runs)
|
|
13
|
-
# task-<id>.status — "running
|
|
13
|
+
# task-<id>.status — "running pid=<N> started=<ISO>"
|
|
14
|
+
# → "complete rc=<N> ended=<ISO>" on clean exit
|
|
15
|
+
# → "aborted rc=<N> signal=<NAME>" on SIGTERM/INT/HUP
|
|
14
16
|
#
|
|
15
|
-
# Exit code: 0 on successful spawn
|
|
17
|
+
# Exit code: 0 on successful spawn, 1 on missing args, 2 on invalid args,
|
|
18
|
+
# 3 on workdir creation failure.
|
|
19
|
+
#
|
|
20
|
+
# Hardening notes (2.7.0):
|
|
21
|
+
# - task-id is validated against an allow-list ([a-zA-Z0-9._-], 1–60 chars,
|
|
22
|
+
# must not start with '.' or '-'). Prevents path traversal via task-id.
|
|
23
|
+
# - workdir must be an absolute path.
|
|
24
|
+
# - Status file is written via tmp + mv so concurrent readers never see a
|
|
25
|
+
# half-written file and the "stuck at running after SIGTERM" failure mode
|
|
26
|
+
# is eliminated.
|
|
27
|
+
# - Child shell has a TERM/INT/HUP trap that records an "aborted" status
|
|
28
|
+
# before exiting, so external kill signals leave a deterministic record.
|
|
16
29
|
#
|
|
17
30
|
# Design notes:
|
|
18
31
|
# - setsid + nohup + disown: triple-armor against SIGHUP when the parent
|
|
19
32
|
# shell exits. The subprocess gets its own session.
|
|
20
33
|
# - stdin closed, stdout/stderr redirected to the log file. No terminal.
|
|
21
34
|
# - The wrapper shell exits immediately after spawning; does NOT wait.
|
|
22
|
-
# - On process exit, an inner wrapper writes "complete rc=<N>" to the
|
|
23
|
-
# status file so a future agent turn can detect completion without
|
|
24
|
-
# racing with the cron monitor's polling.
|
|
25
35
|
|
|
26
36
|
set -euo pipefail
|
|
27
37
|
|
|
@@ -30,29 +40,96 @@ if [[ $# -lt 3 ]]; then
|
|
|
30
40
|
exit 1
|
|
31
41
|
fi
|
|
32
42
|
|
|
33
|
-
|
|
43
|
+
raw_task_id="$1"
|
|
34
44
|
workdir="$2"
|
|
35
45
|
shift 2
|
|
36
46
|
|
|
37
|
-
|
|
47
|
+
# --- task-id validation -----------------------------------------------------
|
|
48
|
+
if [[ -z "$raw_task_id" ]]; then
|
|
49
|
+
echo "detach-task: task-id must not be empty" >&2
|
|
50
|
+
exit 2
|
|
51
|
+
fi
|
|
52
|
+
if [[ ${#raw_task_id} -gt 60 ]]; then
|
|
53
|
+
echo "detach-task: task-id exceeds 60 chars" >&2
|
|
54
|
+
exit 2
|
|
55
|
+
fi
|
|
56
|
+
if [[ "$raw_task_id" =~ [^a-zA-Z0-9._-] ]]; then
|
|
57
|
+
echo "detach-task: task-id contains illegal chars (allowed: alphanumeric, dot, dash, underscore): $raw_task_id" >&2
|
|
58
|
+
exit 2
|
|
59
|
+
fi
|
|
60
|
+
case "$raw_task_id" in
|
|
61
|
+
.* | -*)
|
|
62
|
+
echo "detach-task: task-id must not start with dot or dash: $raw_task_id" >&2
|
|
63
|
+
exit 2
|
|
64
|
+
;;
|
|
65
|
+
esac
|
|
66
|
+
task_id="$raw_task_id"
|
|
67
|
+
|
|
68
|
+
# --- workdir validation -----------------------------------------------------
|
|
69
|
+
if [[ "$workdir" != /* ]]; then
|
|
70
|
+
echo "detach-task: workdir must be an absolute path: $workdir" >&2
|
|
71
|
+
exit 2
|
|
72
|
+
fi
|
|
73
|
+
if ! mkdir -p "$workdir"; then
|
|
74
|
+
echo "detach-task: cannot create workdir: $workdir" >&2
|
|
75
|
+
exit 3
|
|
76
|
+
fi
|
|
77
|
+
|
|
38
78
|
pid_file="$workdir/task-${task_id}.pid"
|
|
39
79
|
cmd_file="$workdir/task-${task_id}.cmd"
|
|
40
80
|
started_file="$workdir/task-${task_id}.started"
|
|
41
81
|
log_file="$workdir/task-${task_id}.log"
|
|
42
82
|
status_file="$workdir/task-${task_id}.status"
|
|
43
83
|
|
|
84
|
+
# --- atomic status writer (parent) -----------------------------------------
|
|
85
|
+
write_status_atomic() {
|
|
86
|
+
local _payload="$1"
|
|
87
|
+
local _tmp="${status_file}.$$.${RANDOM}.tmp"
|
|
88
|
+
printf '%s\n' "$_payload" > "$_tmp"
|
|
89
|
+
mv -f "$_tmp" "$status_file"
|
|
90
|
+
}
|
|
91
|
+
|
|
44
92
|
printf '%s\n' "$*" > "$cmd_file"
|
|
45
|
-
date -u -Iseconds
|
|
46
|
-
|
|
93
|
+
started_at="$(date -u -Iseconds)"
|
|
94
|
+
printf '%s\n' "$started_at" > "$started_file"
|
|
95
|
+
write_status_atomic "running started=$started_at"
|
|
47
96
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
97
|
+
# --- detached child --------------------------------------------------------
|
|
98
|
+
# The inner `bash -c` inherits status/log paths as positional args so we
|
|
99
|
+
# never string-interpolate paths into the script body. The inner script
|
|
100
|
+
# re-implements the atomic writer (functions don't cross process boundaries
|
|
101
|
+
# via `bash -c`). A TERM/INT/HUP trap catches external kill signals and
|
|
102
|
+
# writes a terminal "aborted" status before exiting with the signal's code.
|
|
103
|
+
setsid nohup bash -c '
|
|
104
|
+
set -u
|
|
105
|
+
_status="$1"
|
|
106
|
+
_log="$2"
|
|
107
|
+
shift 2
|
|
108
|
+
_write() {
|
|
109
|
+
local _tmp="${_status}.$$.${RANDOM}.tmp"
|
|
110
|
+
printf "%s\n" "$1" > "$_tmp" && mv -f "$_tmp" "$_status"
|
|
111
|
+
}
|
|
112
|
+
_on_signal() {
|
|
113
|
+
local _sig="$1"
|
|
114
|
+
local _rc=$?
|
|
115
|
+
_write "aborted rc=$_rc signal=$_sig ended=$(date -u -Iseconds)" 2>/dev/null || true
|
|
116
|
+
exit "$_rc"
|
|
117
|
+
}
|
|
118
|
+
trap "_on_signal TERM" TERM
|
|
119
|
+
trap "_on_signal INT" INT
|
|
120
|
+
trap "_on_signal HUP" HUP
|
|
121
|
+
"$@" > "$_log" 2>&1
|
|
122
|
+
rc=$?
|
|
123
|
+
_write "complete rc=$rc ended=$(date -u -Iseconds)"
|
|
124
|
+
' -- "$status_file" "$log_file" "$@" < /dev/null > /dev/null 2>&1 &
|
|
53
125
|
|
|
54
126
|
pid=$!
|
|
55
127
|
disown "$pid" 2>/dev/null || true
|
|
56
128
|
printf '%d\n' "$pid" > "$pid_file"
|
|
57
129
|
|
|
130
|
+
# Finalise the parent status with the PID once known. The child may race us
|
|
131
|
+
# and overwrite with "complete" if the command was very fast — that's fine,
|
|
132
|
+
# the mv is atomic and the final state wins.
|
|
133
|
+
write_status_atomic "running pid=$pid started=$started_at"
|
|
134
|
+
|
|
58
135
|
echo "spawned task=$task_id pid=$pid log=$log_file status=$status_file"
|