@jjh32456/dsh-longlive 1.6.7 → 1.8.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/CHANGELOG.md +70 -1508
- package/LICENSE +1 -1
- package/QUICKSTART.md +34 -13
- package/README.en.md +18 -7
- package/README.md +34 -9
- package/SPEC.md +5 -5
- package/cordis.patch.yml +23 -9
- package/docs/ANSWER-GUARD.md +92 -0
- package/docs/ARCHITECTURE.md +4 -3
- package/docs/AUTO-RECALL-WIRING.md +1 -1
- package/docs/AUTO-RECALL.md +15 -9
- package/docs/CONFIG.md +168 -35
- package/docs/ERRORS.md +17 -5
- package/docs/FAQ.md +7 -7
- package/docs/FEATURES.md +96 -28
- package/docs/MIGRATION-1.6.0.md +2 -2
- package/docs/OPERATIONS.md +6 -6
- package/docs/PANEL-INTEGRATION.md +6 -0
- package/docs/PRIVACY.md +88 -0
- package/docs/QUICKSTART.md +5 -5
- package/docs/README.en.md +4 -2
- package/docs/RESIDENT-WATCHER.md +1 -1
- package/docs/SESSION-WATCH.md +6 -6
- package/docs/TROUBLESHOOTING.md +4 -4
- package/package.json +47 -117
- package/runbook.md +2 -2
- package/scripts/backfill-auto-cards.mjs +98 -0
- package/scripts/install-surgery-task.ps1 +5 -2
- package/scripts/lib/session-watch-fixture.mjs +1 -1
- package/scripts/longlive-doctor.mjs +6 -0
- package/scripts/migrate-180.mjs +163 -0
- package/scripts/recall-index-build.mjs +128 -0
- package/scripts/session-watch-drill.mjs +1 -1
- package/scripts/surgery-run.cmd +1 -1
- package/scripts/unattended-surgery.ps1 +5 -2
- package/scripts/verify-card-anchors.mjs +138 -0
- package/src/actions/audit.js +125 -0
- package/src/actions/evidence.js +122 -0
- package/src/actions/fs.js +162 -0
- package/src/activity/index.js +760 -0
- package/src/activity/model.js +351 -0
- package/src/activity/store.js +644 -0
- package/src/activity/thinking.js +176 -0
- package/src/adapters/constants.js +11 -0
- package/src/adapters/engram/data/aliases.json +51 -0
- package/src/adapters/engram/data/policy.json +8 -0
- package/src/adapters/engram/data/routing-rules.json +546 -0
- package/src/adapters/engram/index.js +235 -0
- package/src/adapters/registry.js +315 -0
- package/src/answer/audit.js +193 -0
- package/src/answer/evidence.js +30 -0
- package/src/answer/guard.js +1370 -0
- package/src/answer/index.js +1067 -0
- package/src/answer/query.js +111 -0
- package/src/answer/second-hop.mjs +101 -0
- package/src/auto-truncate.js +1 -1
- package/src/config.js +171 -47
- package/src/deps.js +6 -4
- package/src/features.js +182 -6
- package/src/heartbeat.js +156 -23
- package/src/identity/handover.js +52 -1
- package/src/identity/index.js +13 -5
- package/src/identity/inject-position.js +2 -2
- package/src/index.js +97 -7
- package/src/lifecycle/gap-clocks.js +328 -0
- package/src/lifecycle/index.js +269 -0
- package/src/live.js +22 -2
- package/src/memory/activity-capture.js +229 -0
- package/src/memory/anchors.js +194 -0
- package/src/memory/audit-records.js +222 -0
- package/src/memory/auto-cards.js +401 -0
- package/src/memory/capture.js +442 -0
- package/src/memory/card-anchors.js +203 -0
- package/src/memory/conflicts.js +106 -0
- package/src/memory/decay.js +311 -0
- package/src/memory/distill.js +471 -0
- package/src/memory/event-index.js +917 -0
- package/src/memory/evidence-chain.js +295 -0
- package/src/memory/evidence.js +145 -0
- package/src/memory/filter-runner.js +1 -1
- package/src/memory/filter.js +5 -1
- package/src/memory/forget-v2.js +410 -0
- package/src/memory/forget.js +71 -0
- package/src/memory/frames-activation.js +247 -0
- package/src/memory/fts-query.js +174 -0
- package/src/memory/governance.js +604 -0
- package/src/memory/index.js +1 -0
- package/src/memory/l2-gate.js +169 -0
- package/src/memory/lock.js +121 -0
- package/src/memory/migrate.js +139 -0
- package/src/memory/recall-v2.js +223 -0
- package/src/memory/recall.js +65 -2
- package/src/memory/records.js +425 -0
- package/src/memory/retention.js +128 -0
- package/src/memory/review.js +124 -0
- package/src/memory/trust.js +88 -0
- package/src/memory/version-chain.js +264 -0
- package/src/memory/wal.js +137 -0
- package/src/memory/working-frame.js +516 -0
- package/src/metrics/classify.mjs +5 -3
- package/src/metrics/index.mjs +21 -1
- package/src/metrics/prestep-latency.mjs +300 -0
- package/src/metrics/store.mjs +25 -0
- package/src/policy-profile.js +18 -3
- package/src/recall/anaphora.mjs +87 -0
- package/src/recall/cards.mjs +7 -0
- package/src/recall/embedding.mjs +8 -8
- package/src/recall/entities.mjs +112 -0
- package/src/recall/index.js +235 -19
- package/src/recall/inject-order.mjs +10 -8
- package/src/recall/privacy.mjs +105 -16
- package/src/recall/recall-core.mjs +116 -10
- package/src/recall/shared-visibility.js +302 -0
- package/src/recall/time-normalizer.mjs +196 -0
- package/src/role/activation.js +191 -0
- package/src/role/attention.js +318 -0
- package/src/role/base.js +36 -0
- package/src/role/channels.js +423 -0
- package/src/role/index.js +425 -0
- package/src/role/interfaces.js +115 -0
- package/src/role/personality.js +370 -0
- package/src/role/readers.js +151 -0
- package/src/role/relationships.js +477 -0
- package/src/role/store.js +202 -0
- package/src/role/writeprotect.js +373 -0
- package/src/router/aliases.json +176 -25
- package/src/router/background/agent-runner.mjs +1 -1
- package/src/router/background/anchor.mjs +1 -1
- package/src/router/background/audit.mjs +2 -2
- package/src/router/background/budget-ledger.mjs +2 -2
- package/src/router/background/host-sim.mjs +1 -1
- package/src/router/background/memory.mjs +4 -4
- package/src/router/background/queue.mjs +1 -1
- package/src/router/background/retry.mjs +1 -1
- package/src/router/background/router.mjs +1 -1
- package/src/router/background/stream.mjs +1 -1
- package/src/router/background/tool-policy.mjs +1 -1
- package/src/router/design-headings.json +5 -5
- package/src/router/face/config.mjs +1 -1
- package/src/router/face/identity.mjs +3 -3
- package/src/router/judge.mjs +8 -7
- package/src/router/policies/generic.json +21 -4
- package/src/router/route.js +109 -22
- package/src/router/router.mjs +10 -6
- package/src/router/routing-rules.json +260 -445
- package/src/router/run-sim.mjs +8 -8
- package/src/router/runtime.js +23 -12
- package/src/router/service/board.mjs +95 -15
- package/src/router/service/config.mjs +5 -5
- package/src/router/service/context.mjs +1 -1
- package/src/router/service/hint.mjs +14 -0
- package/src/router/service/queue.mjs +1 -1
- package/src/router/service/service.mjs +27 -11
- package/src/router/shadow.mjs +4 -3
- package/src/surgery-recovery.js +2 -2
- package/src/tool-output.js +2 -2
- package/src/tools.js +39 -7
- package/src/truncate-visible.js +2 -2
- package/src/ui/actions.js +1312 -0
- package/src/ui/panel-api.js +367 -0
- package/src/ui/panel-auth.js +251 -0
- package/src/ui/panel-integrity.js +243 -0
- package/src/ui/routes-readonly.js +695 -0
- package/src/ui/routes.js +3 -0
- package/docs/DEV.md +0 -279
- package/docs/PRESENCE-BUS-WIRING.md +0 -491
- package/docs/PRESENCE-BUS.md +0 -694
- package/docs/SURGERY.md +0 -186
- package/scripts/mark-core-cards.mjs +0 -289
- package/scripts/pack.mjs +0 -392
- package/scripts/router-proposals.mjs +0 -386
- package/src/router/fixtures/M1.json +0 -16
- package/src/router/fixtures/M2.json +0 -16
- package/src/router/fixtures/M3.json +0 -20
- package/src/router/fixtures/M4.json +0 -20
- package/src/router/fixtures/M5.json +0 -45
- package/src/router/fixtures/M6.json +0 -53
- package/src/router/fixtures/M7.json +0 -46
- package/src/router/fixtures/S1.json +0 -20
- package/src/router/fixtures/S2.json +0 -23
- package/src/router/fixtures/S3.json +0 -20
- package/src/router/fixtures/S4.json +0 -34
- package/src/router/fixtures/S5.json +0 -43
- package/src/router/fixtures/S6.json +0 -47
- package/src/router/fixtures/T1.json +0 -23
- package/src/router/fixtures/T2.json +0 -16
- package/src/router/fixtures/T3.json +0 -19
- package/src/router/fixtures/T4.json +0 -16
- package/src/router/fixtures/X1.json +0 -17
- package/src/router/fixtures/X2.json +0 -20
- package/src/router/gen-design-headings.mjs +0 -107
- package/src/router/policies/owner-rulings-2026-11-03.json +0 -62
- package/test/auto-recall.test.mjs +0 -474
- package/test/auto-truncate.test.mjs +0 -931
- package/test/autobind.test.mjs +0 -385
- package/test/bus.test.mjs +0 -1572
- package/test/cli-guard.test.mjs +0 -198
- package/test/conclusion.test.mjs +0 -408
- package/test/config-schema.test.mjs +0 -204
- package/test/d6-output.test.mjs +0 -194
- package/test/d6.test.mjs +0 -395
- package/test/deps.test.mjs +0 -342
- package/test/doctor-setup.test.mjs +0 -297
- package/test/embedding-recall.test.mjs +0 -347
- package/test/feature-flags.test.mjs +0 -568
- package/test/filter-shadow.test.mjs +0 -170
- package/test/fixtures/baseline-0.8.0-registration.json +0 -556
- package/test/fixtures/d6-header-tools.json +0 -1
- package/test/fixtures/lock-child.mjs +0 -67
- package/test/fixtures/pre-step-container.mjs +0 -100
- package/test/fixtures/privacy-memory/topics/pii-unmarked.md +0 -9
- package/test/fixtures/privacy-memory/topics/secret-local-only.md +0 -11
- package/test/fixtures/profile-session-longlive-config.json +0 -20
- package/test/fixtures/proposal-cas-child.mjs +0 -66
- package/test/host-engine-status.test.mjs +0 -307
- package/test/hot-truncate.test.mjs +0 -1349
- package/test/identity-card-marker.test.mjs +0 -307
- package/test/identity-router/run.mjs +0 -721
- package/test/integration-pre-step.test.mjs +0 -553
- package/test/live.test.mjs +0 -1020
- package/test/maintenance-schedule.test.mjs +0 -538
- package/test/memory.test.mjs +0 -2828
- package/test/metrics.test.mjs +0 -478
- package/test/orchestrator.test.mjs +0 -266
- package/test/p1_probe.mjs +0 -97
- package/test/packaging.test.mjs +0 -182
- package/test/portability.test.mjs +0 -343
- package/test/rc4-regressions.test.mjs +0 -562
- package/test/rc5-regressions.test.mjs +0 -197
- package/test/rc6-chinese.test.mjs +0 -394
- package/test/router-1100/apply-off.test.mjs +0 -175
- package/test/router-1100/budget-reconcile.test.mjs +0 -215
- package/test/router-1100/config-context.test.mjs +0 -211
- package/test/router-1100/helpers.mjs +0 -129
- package/test/router-1100/hint-envelope.test.mjs +0 -150
- package/test/router-1100/lock-crossproc.test.mjs +0 -206
- package/test/router-1100/proposal-cas-crossproc.test.mjs +0 -184
- package/test/router-1100/router-apply.test.mjs +0 -372
- package/test/router-1100/router-fixb.test.mjs +0 -602
- package/test/router-1100/router-proposals.test.mjs +0 -405
- package/test/router-1100/router-queue-lease-wal.test.mjs +0 -355
- package/test/router-1100/router-security-cr.test.mjs +0 -333
- package/test/router-1100/service-lifecycle.test.mjs +0 -220
- package/test/router-1100/tools-contract.test.mjs +0 -164
- package/test/router-1100/turn-reflect-tick.test.mjs +0 -89
- package/test/router-1100/v6-contract.test.mjs +0 -158
- package/test/router-1100/v6b-contract.test.mjs +0 -293
- package/test/router-1100/v6c-contract.test.mjs +0 -249
- package/test/router-1100/wal-rotation.test.mjs +0 -375
- package/test/router-1100/wp1-config.test.mjs +0 -170
- package/test/router-1100/wp1-default-off.test.mjs +0 -77
- package/test/router-1100/wp1-model-status.test.mjs +0 -90
- package/test/router-1100/wp1-status.test.mjs +0 -220
- package/test/router-1100/wp1-tools.test.mjs +0 -146
- package/test/router-1100/wp5-cli.test.mjs +0 -240
- package/test/router-1100/wp5-model-auto.test.mjs +0 -418
- package/test/router-1100/wp6-merge.test.mjs +0 -386
- package/test/router-1100/wp6-wake.test.mjs +0 -502
- package/test/router-background/audit.test.mjs +0 -37
- package/test/router-background/budget-ledger.test.mjs +0 -330
- package/test/router-background/cross-process.test.mjs +0 -222
- package/test/router-background/fixtures/cross-child.mjs +0 -85
- package/test/router-background/fixtures/real-shapes.mjs +0 -239
- package/test/router-background/router.test.mjs +0 -1044
- package/test/router-background/stream-retry.test.mjs +0 -358
- package/test/router-background/tool-agent.test.mjs +0 -384
- package/test/router-face/bridge.test.mjs +0 -169
- package/test/router-face/face.test.mjs +0 -316
- package/test/router-failclosed.test.mjs +0 -466
- package/test/router-identity.test.mjs +0 -384
- package/test/router-l1-l2.contract.test.mjs +0 -1075
- package/test/router-memory-tools.test.mjs +0 -262
- package/test/router-policy.test.mjs +0 -225
- package/test/router-runtime.test.mjs +0 -438
- package/test/router-shadow.test.mjs +0 -287
- package/test/router.test.mjs +0 -903
- package/test/run-rc.mjs +0 -299
- package/test/run.mjs +0 -2469
- package/test/safety-defaults.test.mjs +0 -179
- package/test/seeded-load.test.mjs +0 -436
- package/test/session-original.test.mjs +0 -338
- package/test/surgery-recovery.test.mjs +0 -936
- package/test/t7_drive.mjs +0 -151
- package/test/tool-output.test.mjs +0 -393
- package/test/tool-schema.test.mjs +0 -177
- package/test/tools_contract.test.mjs +0 -716
- package/test/truncate-visible.test.mjs +0 -1150
- package/test/ui-flags.test.mjs +0 -477
- package/test/v4-hardening.test.mjs +0 -427
|
@@ -1,556 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"provenance": {
|
|
3
|
-
"source": "merged 1.4.0-rc.3 tree (0.8.0 registration contract + D3 session_original)",
|
|
4
|
-
"version": "1.4.0-rc.3",
|
|
5
|
-
"node": "v24.21.0",
|
|
6
|
-
"note": "Regenerated by _work2/gen-baseline.mjs after D3 added the 22nd tool; all flags off, metrics off, routerRuntime off. Do not hand-edit."
|
|
7
|
-
},
|
|
8
|
-
"returned": {},
|
|
9
|
-
"toolCount": 22,
|
|
10
|
-
"tools": [
|
|
11
|
-
{
|
|
12
|
-
"name": "session_health",
|
|
13
|
-
"description": "Inspect a DSH session log (session.v4.jsonl.zstd): size, event count, last event type, visible-message count and sha256, age, backups, last truncation. Read-only. Pass sessionPath, sessionId, or session:\"latest\"/\"current\".",
|
|
14
|
-
"parameters": {
|
|
15
|
-
"sessionPath": {
|
|
16
|
-
"type": "string",
|
|
17
|
-
"description": "Absolute path to a session.v4.jsonl.zstd file (highest priority)."
|
|
18
|
-
},
|
|
19
|
-
"sessionId": {
|
|
20
|
-
"type": "string",
|
|
21
|
-
"description": "Session id (the folder name under <DSH_HOME>/sessions/<scope>/)."
|
|
22
|
-
},
|
|
23
|
-
"session": {
|
|
24
|
-
"type": "string",
|
|
25
|
-
"description": "Shortcut instead of an id: \"latest\" (most recently modified log) or \"current\"."
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
"hasExecute": true
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"name": "session_original",
|
|
32
|
-
"description": "D3 \"fetch the original\": return the text of ONE turn from a session log, including tool output that was compressed out of the context. Read-only and privacy-gated: the FULL selection is scanned before slicing, so maxBytes/offset cannot page around a match. turn is required and 1-based (a user message belongs to its preceding turn/start). kind defaults to \"tool\" (tool results); use \"message\" for user/assistant text, \"call\" for tool arguments, or \"all\". Narrow a turn with toolCallId, or with messageIndex (0-based among the turn's user/assistant messages). The response is capped at maxBytes UTF-8 bytes (default 65536, config originalFetchMaxBytes): when truncated, content stops on a code-point boundary and nextOffset is the byte offset for the next call. Find a turn first with session_search or memory_recall. The result also reports the D2 archive path <memoryRoot>/.longlive/tool-output/<turn>/<id>.txt but NEVER writes it. Pass sessionPath, sessionId, or session:\"latest\"/\"current\".",
|
|
33
|
-
"parameters": {
|
|
34
|
-
"sessionPath": {
|
|
35
|
-
"type": "string",
|
|
36
|
-
"description": "Absolute path to a session.v4.jsonl.zstd file (highest priority)."
|
|
37
|
-
},
|
|
38
|
-
"sessionId": {
|
|
39
|
-
"type": "string",
|
|
40
|
-
"description": "Session id (the folder name under <DSH_HOME>/sessions/<scope>/)."
|
|
41
|
-
},
|
|
42
|
-
"session": {
|
|
43
|
-
"type": "string",
|
|
44
|
-
"description": "Shortcut instead of an id: \"latest\" (most recently modified log) or \"current\"."
|
|
45
|
-
},
|
|
46
|
-
"turn": {
|
|
47
|
-
"type": "integer",
|
|
48
|
-
"description": "Required. 1-based turn number (the value in turn/start events)."
|
|
49
|
-
},
|
|
50
|
-
"kind": {
|
|
51
|
-
"type": "string",
|
|
52
|
-
"enum": [
|
|
53
|
-
"tool",
|
|
54
|
-
"message",
|
|
55
|
-
"call",
|
|
56
|
-
"all"
|
|
57
|
-
],
|
|
58
|
-
"description": "Default \"tool\" (tool results). \"message\" = user/assistant text, \"call\" = tool arguments, \"all\" = every item in the turn."
|
|
59
|
-
},
|
|
60
|
-
"toolCallId": {
|
|
61
|
-
"type": "string",
|
|
62
|
-
"description": "Select one tool call/result by call id (the toolCallId on the result event)."
|
|
63
|
-
},
|
|
64
|
-
"messageIndex": {
|
|
65
|
-
"type": "integer",
|
|
66
|
-
"description": "Select one message by its 0-based index among the turn's user/assistant messages."
|
|
67
|
-
},
|
|
68
|
-
"offset": {
|
|
69
|
-
"type": "integer",
|
|
70
|
-
"description": "Byte offset into the full selection for paging (default 0). Use nextOffset from a truncated response."
|
|
71
|
-
},
|
|
72
|
-
"maxBytes": {
|
|
73
|
-
"type": "integer",
|
|
74
|
-
"description": "Byte cap for this call (default config originalFetchMaxBytes = 65536; clamped to 1024..4194304)."
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
"hasExecute": true
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
"name": "session_backup",
|
|
81
|
-
"description": "Plan or create a byte-identical backup of a session log next to it (session.v4.jsonl.zstd.bak-YYYYMMDD, sha256 verified). dryRun=true writes nothing. Pass sessionPath, sessionId, or session:\"latest\"/\"current\".",
|
|
82
|
-
"parameters": {
|
|
83
|
-
"sessionPath": {
|
|
84
|
-
"type": "string",
|
|
85
|
-
"description": "Absolute path to a session.v4.jsonl.zstd file (highest priority)."
|
|
86
|
-
},
|
|
87
|
-
"sessionId": {
|
|
88
|
-
"type": "string",
|
|
89
|
-
"description": "Session id (the folder name under <DSH_HOME>/sessions/<scope>/)."
|
|
90
|
-
},
|
|
91
|
-
"session": {
|
|
92
|
-
"type": "string",
|
|
93
|
-
"description": "Shortcut instead of an id: \"latest\" (most recently modified log) or \"current\"."
|
|
94
|
-
},
|
|
95
|
-
"dryRun": {
|
|
96
|
-
"type": "boolean",
|
|
97
|
-
"description": "Default true: only report the planned backup."
|
|
98
|
-
},
|
|
99
|
-
"confirm": {
|
|
100
|
-
"type": "string",
|
|
101
|
-
"description": "Pass \"BACKUP\" to actually create the backup."
|
|
102
|
-
}
|
|
103
|
-
},
|
|
104
|
-
"hasExecute": true
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
"name": "session_truncate",
|
|
108
|
-
"description": "Safely drop the oldest events of a session log while keeping the visible conversation byte-identical (verified by a deriveMessages digest), with backup, tmp verify and rollback. dryRun=true writes nothing; writing requires confirm:\"TRUNCATE\". Refuses the session this app has loaded (VISIBLE_TARGET_IS_LIVE_SESSION; unknown caller id: VISIBLE_CURRENT_ID_UNKNOWN): stop the app first. Pass sessionPath, sessionId, or session:\"latest\"/\"current\".",
|
|
109
|
-
"parameters": {
|
|
110
|
-
"sessionPath": {
|
|
111
|
-
"type": "string",
|
|
112
|
-
"description": "Absolute path to a session.v4.jsonl.zstd file (highest priority)."
|
|
113
|
-
},
|
|
114
|
-
"sessionId": {
|
|
115
|
-
"type": "string",
|
|
116
|
-
"description": "Session id (the folder name under <DSH_HOME>/sessions/<scope>/)."
|
|
117
|
-
},
|
|
118
|
-
"session": {
|
|
119
|
-
"type": "string",
|
|
120
|
-
"description": "Shortcut instead of an id: \"latest\" (most recently modified log) or \"current\"."
|
|
121
|
-
},
|
|
122
|
-
"keepEvents": {
|
|
123
|
-
"type": "integer",
|
|
124
|
-
"description": "How many trailing events to keep (integer >= 1, default 20000)."
|
|
125
|
-
},
|
|
126
|
-
"dryRun": {
|
|
127
|
-
"type": "boolean",
|
|
128
|
-
"description": "Default true: plan and verify without writing."
|
|
129
|
-
},
|
|
130
|
-
"confirm": {
|
|
131
|
-
"type": "string",
|
|
132
|
-
"description": "Pass \"TRUNCATE\" to actually rewrite the log."
|
|
133
|
-
},
|
|
134
|
-
"allowLive": {
|
|
135
|
-
"type": "boolean",
|
|
136
|
-
"description": "Diagnostics only. Bypass the live-session refusal; also requires confirm:\"I-KNOW-THIS-CORRUPTS\". Never use it on the session this app has loaded."
|
|
137
|
-
}
|
|
138
|
-
},
|
|
139
|
-
"hasExecute": true
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
"name": "session_truncate_visible",
|
|
143
|
-
"description": "Drop whole turns from the FRONT of the visible conversation so the model actually receives less context. The cut is always on a turn boundary; the first user-authored message survives (copied into the retained head when its turn is dropped); a protected system/message is kept; a synthetic user/message archive card records what was removed. The removed prefix is archived under <session>.archive/<ts>.jsonl.zstd; seq is renumbered 0..n-1; the write is tmp + fsync + atomic rename with read-back verification and an inflight rollback record. dryRun=true writes nothing; writing requires confirm:\"TRUNCATE-VISIBLE\". Refuses the session this app has loaded (VISIBLE_TARGET_IS_LIVE_SESSION; unknown caller id: VISIBLE_CURRENT_ID_UNKNOWN): truncate it only while the app is stopped. Defaults: keepTurns=12, keepTokens=80000 (the later boundary wins). When the first user message is dropped it is carried as a bounded prefix (firstUserCapChars, default 4000) that names the archive instead of copying megabytes; the post-cut token budget counts that card, the archive card and the protected head. An unstable boundary is retried by dropping one more turn (boundaryRetries, default 3); if no cut fits, the result is feasible=false with the attempted cuts, never a silent success. Pass sessionPath, sessionId, or session:\"latest\"/\"current\".",
|
|
144
|
-
"parameters": {
|
|
145
|
-
"sessionPath": {
|
|
146
|
-
"type": "string",
|
|
147
|
-
"description": "Absolute path to a session.v4.jsonl.zstd file (highest priority)."
|
|
148
|
-
},
|
|
149
|
-
"sessionId": {
|
|
150
|
-
"type": "string",
|
|
151
|
-
"description": "Session id (the folder name under <DSH_HOME>/sessions/<scope>/)."
|
|
152
|
-
},
|
|
153
|
-
"session": {
|
|
154
|
-
"type": "string",
|
|
155
|
-
"description": "Shortcut instead of an id: \"latest\" (most recently modified log) or \"current\"."
|
|
156
|
-
},
|
|
157
|
-
"keepTurns": {
|
|
158
|
-
"type": "integer",
|
|
159
|
-
"description": "Keep at least this many trailing turns (integer >= 1, default 12)."
|
|
160
|
-
},
|
|
161
|
-
"keepTokens": {
|
|
162
|
-
"type": "integer",
|
|
163
|
-
"description": "Keep at least this many estimated trailing message tokens (integer >= 1, default 80000)."
|
|
164
|
-
},
|
|
165
|
-
"firstUserCapChars": {
|
|
166
|
-
"type": "integer",
|
|
167
|
-
"description": "Cap the carried first user message at this many characters (integer >= 1, default 4000); the full text stays in the archive."
|
|
168
|
-
},
|
|
169
|
-
"boundaryRetries": {
|
|
170
|
-
"type": "integer",
|
|
171
|
-
"description": "When the cut boundary cannot be stabilized, retry with one more dropped turn this many times (integer >= 0, default 3)."
|
|
172
|
-
},
|
|
173
|
-
"dryRun": {
|
|
174
|
-
"type": "boolean",
|
|
175
|
-
"description": "Default true: plan and report without writing."
|
|
176
|
-
},
|
|
177
|
-
"confirm": {
|
|
178
|
-
"type": "string",
|
|
179
|
-
"description": "Pass \"TRUNCATE-VISIBLE\" to actually rewrite the log."
|
|
180
|
-
},
|
|
181
|
-
"carryFirstUserMessage": {
|
|
182
|
-
"type": "boolean",
|
|
183
|
-
"description": "Copy the first user-authored message into the retained head when its turn is dropped (default true)."
|
|
184
|
-
},
|
|
185
|
-
"insertArchiveCard": {
|
|
186
|
-
"type": "boolean",
|
|
187
|
-
"description": "Insert the synthetic [已归档 ...] user/message card (default true). Set false if the host rejects it."
|
|
188
|
-
},
|
|
189
|
-
"allowLive": {
|
|
190
|
-
"type": "boolean",
|
|
191
|
-
"description": "Diagnostics only. Bypass the live-session refusal; also requires confirm:\"I-KNOW-THIS-CORRUPTS\". Never use it on the session this app has loaded."
|
|
192
|
-
}
|
|
193
|
-
},
|
|
194
|
-
"hasExecute": true
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
"name": "session_compact",
|
|
198
|
-
"description": "Trigger one native harness compaction so the summary is written into the session log (compaction/summary + compact-checkpoint) instead of living in process memory. This is the only way to make a long session shorter without losing what it knows; run it BEFORE session_truncate, because truncation can only delete history a compaction already shadowed. dryRun=true only reports availability. When called inside a running turn the request is queued until the agent goes idle.",
|
|
199
|
-
"parameters": {
|
|
200
|
-
"dryRun": {
|
|
201
|
-
"type": "boolean",
|
|
202
|
-
"description": "Default true: only report whether compaction is available."
|
|
203
|
-
},
|
|
204
|
-
"sourceCommandId": {
|
|
205
|
-
"type": "string",
|
|
206
|
-
"description": "Optional command identity recorded on the compaction."
|
|
207
|
-
}
|
|
208
|
-
},
|
|
209
|
-
"hasExecute": true
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
"name": "session_wake",
|
|
213
|
-
"description": "Read a bounded wake-up slice of the memory store (default <DSH home>/longlive-memory; override with plugin config memoryRoot / memRoot or $DSH_LONGLIVE_MEMORY_ROOT, legacy $DSH_MEM): the STATE.md sections 我在哪 / 在等什么 / 最近三件 (400 chars each), flow/current.md (800 chars max), the last three \"##\" headings of the newest journal/*.md (newest by year/month, not by string sort), and up to 20 INDEX.md lines shorter than 60 chars. Read-only. Missing files are skipped with a note instead of failing; an absent memory root reports unavailable. The text is capped at 2500 characters; truncated is true whenever a section or the whole text was cut.",
|
|
214
|
-
"parameters": {
|
|
215
|
-
"session": {
|
|
216
|
-
"type": "string",
|
|
217
|
-
"description": "Optional session label for the caller. It never selects or replaces memory content; newlines and \"#\" are stripped before it can appear in the text."
|
|
218
|
-
}
|
|
219
|
-
},
|
|
220
|
-
"hasExecute": true
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
"name": "lease_acquire",
|
|
224
|
-
"description": "Atomically take the memory-store write lease (<memoryRoot>/.lease, default <DSH home>/longlive-memory/.lease; override with memoryRoot / memRoot, $DSH_LONGLIVE_MEMORY_ROOT, or legacy $DSH_MEM). Concurrency-safe across processes (O_EXCL create): exactly one caller gets ok:true. An existing, unexpired lease returns ok:false with its holder and acquiredAt (reason \"held by another writer\"); an expired or unparseable lease is replaced, retried exactly once.",
|
|
225
|
-
"parameters": {
|
|
226
|
-
"holder": {
|
|
227
|
-
"type": "string",
|
|
228
|
-
"description": "Who wants the lease (a process/session name). Required."
|
|
229
|
-
},
|
|
230
|
-
"ttlSec": {
|
|
231
|
-
"type": "integer",
|
|
232
|
-
"description": "Lease lifetime in whole seconds (integer 1..86400, default 300). A day is the ceiling: a longer lease is a typo, not a plan."
|
|
233
|
-
}
|
|
234
|
-
},
|
|
235
|
-
"hasExecute": true
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
"name": "lease_release",
|
|
239
|
-
"description": "Release the memory-store write lease, but only for the holder recorded inside it. No file reports ok:false reason \"no lease\"; a different holder reports ok:false reason \"not the holder\" and the lease is left in place.",
|
|
240
|
-
"parameters": {
|
|
241
|
-
"holder": {
|
|
242
|
-
"type": "string",
|
|
243
|
-
"description": "Who is releasing; must match the recorded holder. Required."
|
|
244
|
-
}
|
|
245
|
-
},
|
|
246
|
-
"hasExecute": true
|
|
247
|
-
},
|
|
248
|
-
{
|
|
249
|
-
"name": "worker_spawn",
|
|
250
|
-
"description": "Dispatch one background child session (worker) through the host subagents service and return immediately with its workerId. The child runs in its own context and reports back through the host; read its state with worker_status and stop it with worker_kill. Pass prompt (required: the task text), an optional label, and timeoutSec (default 600).",
|
|
251
|
-
"parameters": {
|
|
252
|
-
"prompt": {
|
|
253
|
-
"type": "string",
|
|
254
|
-
"description": "The task to hand to the child session. Required."
|
|
255
|
-
},
|
|
256
|
-
"label": {
|
|
257
|
-
"type": "string",
|
|
258
|
-
"description": "Optional short label for the child (defaults to the prompt head)."
|
|
259
|
-
},
|
|
260
|
-
"timeoutSec": {
|
|
261
|
-
"type": "integer",
|
|
262
|
-
"description": "How long the dispatch itself may take, in whole seconds (integer >= 1, default 600)."
|
|
263
|
-
}
|
|
264
|
-
},
|
|
265
|
-
"hasExecute": true
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
"name": "worker_status",
|
|
269
|
-
"description": "Report where a worker stands: live status from the Agent registry, else the parent child catalog, else its persisted session log (events count, last message time, status). Pass workerId (required), the id worker_spawn returned.",
|
|
270
|
-
"parameters": {
|
|
271
|
-
"workerId": {
|
|
272
|
-
"type": "string",
|
|
273
|
-
"description": "The worker id returned by worker_spawn. Required."
|
|
274
|
-
}
|
|
275
|
-
},
|
|
276
|
-
"hasExecute": true
|
|
277
|
-
},
|
|
278
|
-
{
|
|
279
|
-
"name": "worker_kill",
|
|
280
|
-
"description": "Stop one running worker through the host subagents service (interrupt, fire-and-return). A worker that is not running reports unavailable instead of a fake success. Pass workerId (required) and an optional reason.",
|
|
281
|
-
"parameters": {
|
|
282
|
-
"workerId": {
|
|
283
|
-
"type": "string",
|
|
284
|
-
"description": "The worker id returned by worker_spawn. Required."
|
|
285
|
-
},
|
|
286
|
-
"reason": {
|
|
287
|
-
"type": "string",
|
|
288
|
-
"description": "Optional short reason recorded in the report."
|
|
289
|
-
}
|
|
290
|
-
},
|
|
291
|
-
"hasExecute": true
|
|
292
|
-
},
|
|
293
|
-
{
|
|
294
|
-
"name": "memory_index",
|
|
295
|
-
"description": "Rebuild the generated section of <memoryRoot>/INDEX.md from every card under topics/, journal/ and procedures/. Only the region between <!-- BEGIN GENERATED --> and <!-- END GENERATED --> is replaced; hand-written content outside is preserved byte-for-byte. Cards without frontmatter are legacy cards and still get a row. Procedures get their own 「程序性」 table (name / trigger / path / strength / version) so they are counted without appearing twice; a broken procedure card is listed as an invalid row instead of failing the run. Default is dry-run (returns the section and the resulting file, writes nothing); pass apply:true to write. Memory root: plugin config memoryRoot (alias memRoot), else $DSH_LONGLIVE_MEMORY_ROOT, else legacy $DSH_MEM, else <DSH home>/longlive-memory (created on demand).",
|
|
296
|
-
"parameters": {
|
|
297
|
-
"apply": {
|
|
298
|
-
"type": "boolean",
|
|
299
|
-
"description": "Default false (dry-run). true rewrites only the generated section, after backing INDEX.md up."
|
|
300
|
-
}
|
|
301
|
-
},
|
|
302
|
-
"hasExecute": true
|
|
303
|
-
},
|
|
304
|
-
{
|
|
305
|
-
"name": "memory_consolidate",
|
|
306
|
-
"description": "Read journal/*.md entries dated after the last consolidation (or an explicit since) and produce a proposal report: which paragraph belongs in which card, why, a 120-char excerpt, and a suggested salience. Journal paragraphs may carry `<!-- affect: N | reason -->` (N 1..5); the marker wins over the regex fallback, and malformed markers are listed under badAffect without failing the run. Every proposal gets a stable id (sha1(source paragraph text)[:12]); ids already in state.seenProposals are never proposed again. Report only — it never edits a card. It writes exactly one file under <memoryRoot>/.longlive/reports/ and records new proposal ids in memory-state.json; lastConsolidated advances only after every proposal for the newest scanned day is resolved (accepted/rejected/superseded). There is no apply flag by design.",
|
|
307
|
-
"parameters": {
|
|
308
|
-
"since": {
|
|
309
|
-
"type": "string",
|
|
310
|
-
"description": "Optional YYYY-MM-DD override for the incremental start; defaults to memory-state.json lastConsolidated."
|
|
311
|
-
}
|
|
312
|
-
},
|
|
313
|
-
"hasExecute": true
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
"name": "memory_reinforce",
|
|
317
|
-
"description": "Record one real use of a card: strength = min(9, strength+1), last_used = today, revisions += 1, plus one <!-- rev: ... --> line with the reason. The prose body must stay byte-identical; the original is backed up to <memoryRoot>/.longlive/backups/ before writing, and any post-write mismatch rolls the card back. Pass path (required, relative to memoryRoot or absolute inside it).",
|
|
318
|
-
"parameters": {
|
|
319
|
-
"path": {
|
|
320
|
-
"type": "string",
|
|
321
|
-
"description": "The card to reinforce, relative to memoryRoot or an absolute path inside it. Required."
|
|
322
|
-
},
|
|
323
|
-
"reason": {
|
|
324
|
-
"type": "string",
|
|
325
|
-
"description": "Optional short reason stored in the rev comment (default \"被真实使用\")."
|
|
326
|
-
}
|
|
327
|
-
},
|
|
328
|
-
"hasExecute": true
|
|
329
|
-
},
|
|
330
|
-
{
|
|
331
|
-
"name": "memory_forget",
|
|
332
|
-
"description": "Propose forgetting by decay rules: last_used > 90 days and strength <= 2 demotes to epochs/, last_used > 365 days tombstones. Cards with salience >= 5 are never proposed. Default is dry-run and writes nothing: it only reports proposals and whether epochs/, archive/tombstones/ and .longlive/backups exist. Execution requires confirm:\"FORGET\": it creates those paths, backs up each card into .longlive/backups/ first, rewrites tombstones.md atomically with a three-question epitaph per card (reason / affects / stillUseful) BEFORE moving the card to archive/tombstones/ (or epochs/), appends exactly one line to .longlive/audit.log, and never deletes a file.",
|
|
333
|
-
"parameters": {
|
|
334
|
-
"confirm": {
|
|
335
|
-
"type": "string",
|
|
336
|
-
"description": "Default absent = dry-run. Pass \"FORGET\" to execute the proposals."
|
|
337
|
-
}
|
|
338
|
-
},
|
|
339
|
-
"hasExecute": true
|
|
340
|
-
},
|
|
341
|
-
{
|
|
342
|
-
"name": "memory_procedure",
|
|
343
|
-
"description": "Procedural memory: how a task is done, not what happened. One card per procedure at <memoryRoot>/procedures/<slug>.md. Frontmatter is required: name / trigger / salience / strength / last_used (plus revisions). Body sections: 何时用 / 怎么做 (a numbered list) / 失败模式 / 例子. action:\"save\" creates or merges by slug (same slug -> revisions+1, the old version is backed up under .longlive/backups/, and fields you omit keep their old value); a NEW card needs name plus when and at least one step. action:\"list\" filters by trigger keyword (space or comma separated, case-insensitive, OR over keywords); action:\"get\" returns one card including its raw text; action:\"report\" records one real use: success -> strength+1, failure -> strength-1 (clamped to 0..9), last_used = today, plus one <!-- rev: ... --> line. report leaves revisions alone: revisions counts content versions, strength counts how often it worked. A card whose frontmatter is broken or misses a required field is reported with E_PROCEDURE_INVALID and is never silently overwritten.",
|
|
344
|
-
"parameters": {
|
|
345
|
-
"action": {
|
|
346
|
-
"type": "string",
|
|
347
|
-
"enum": [
|
|
348
|
-
"save",
|
|
349
|
-
"list",
|
|
350
|
-
"get",
|
|
351
|
-
"report"
|
|
352
|
-
],
|
|
353
|
-
"description": "Required. save | list | get | report."
|
|
354
|
-
},
|
|
355
|
-
"name": {
|
|
356
|
-
"type": "string",
|
|
357
|
-
"description": "Card title (frontmatter name). save derives the slug from it when slug is absent; get/report accept it instead of slug."
|
|
358
|
-
},
|
|
359
|
-
"slug": {
|
|
360
|
-
"type": "string",
|
|
361
|
-
"description": "File stem under procedures/. save/get/report may pass it explicitly (no path separators, no ..)."
|
|
362
|
-
},
|
|
363
|
-
"trigger": {
|
|
364
|
-
"type": "array",
|
|
365
|
-
"items": {
|
|
366
|
-
"type": "string"
|
|
367
|
-
},
|
|
368
|
-
"description": "When this procedure applies (frontmatter trigger). save replaces the whole list; list uses the keywords as an OR filter."
|
|
369
|
-
},
|
|
370
|
-
"salience": {
|
|
371
|
-
"type": "integer",
|
|
372
|
-
"description": "Importance 1..5 (default 3 on a new card, kept on merge unless given)."
|
|
373
|
-
},
|
|
374
|
-
"strength": {
|
|
375
|
-
"type": "integer",
|
|
376
|
-
"description": "How often it worked 0..9 (default 3 on a new card; report changes it, save sets it explicitly)."
|
|
377
|
-
},
|
|
378
|
-
"when": {
|
|
379
|
-
"type": "string",
|
|
380
|
-
"description": "Body section 「何时用」: the situation that calls for this procedure. Required for a new card."
|
|
381
|
-
},
|
|
382
|
-
"steps": {
|
|
383
|
-
"type": "array",
|
|
384
|
-
"items": {
|
|
385
|
-
"type": "string"
|
|
386
|
-
},
|
|
387
|
-
"description": "Body section 「怎么做」: ordered steps, written as a numbered list. Required (at least one) for a new card. A single string with newlines is accepted too."
|
|
388
|
-
},
|
|
389
|
-
"failureModes": {
|
|
390
|
-
"type": "string",
|
|
391
|
-
"description": "Optional body section 「失败模式」: how this procedure goes wrong."
|
|
392
|
-
},
|
|
393
|
-
"example": {
|
|
394
|
-
"type": "string",
|
|
395
|
-
"description": "Optional body section 「例子」: one concrete run."
|
|
396
|
-
},
|
|
397
|
-
"outcome": {
|
|
398
|
-
"type": "string",
|
|
399
|
-
"enum": [
|
|
400
|
-
"success",
|
|
401
|
-
"failure"
|
|
402
|
-
],
|
|
403
|
-
"description": "report only, required: success raises strength by 1, failure lowers it by 1."
|
|
404
|
-
},
|
|
405
|
-
"reason": {
|
|
406
|
-
"type": "string",
|
|
407
|
-
"description": "report only: short reason stored in the rev comment."
|
|
408
|
-
},
|
|
409
|
-
"limit": {
|
|
410
|
-
"type": "integer",
|
|
411
|
-
"description": "list only: page size (default 50, max 500). total/count/truncated are always reported."
|
|
412
|
-
}
|
|
413
|
-
},
|
|
414
|
-
"hasExecute": true
|
|
415
|
-
},
|
|
416
|
-
{
|
|
417
|
-
"name": "memory_recall",
|
|
418
|
-
"description": "Search memory cards by meaning-ish keywords and get the best few back. Mixed, reproducible score: title hits *5 + tags *3 + body frequency (capped 3) + whole-query phrase bonus + character-bigram Dice similarity. Returns {path, title, score, excerpt} sorted by score desc then path asc; the same tree and query always produce byte-identical results. Defaults: topK 3 (1..20), room any, status active+locked — already-locked cards are searchable. Pass status:\"archived\" or \"any\" to widen, room:\"topics\" to narrow. READ-ONLY: it never writes a card, never builds INDEX.md and never creates .longlive/. An empty query throws E_RECALL_EMPTY_QUERY; no hit is not an error — it returns an empty results list with code E_RECALL_NO_MATCH and a hint.",
|
|
419
|
-
"parameters": {
|
|
420
|
-
"query": {
|
|
421
|
-
"type": "string",
|
|
422
|
-
"description": "Required. Natural language or keywords, e.g. \"听觉 训练\"."
|
|
423
|
-
},
|
|
424
|
-
"topK": {
|
|
425
|
-
"type": "integer",
|
|
426
|
-
"description": "How many cards to return (default 3, clamped to 1..20)."
|
|
427
|
-
},
|
|
428
|
-
"room": {
|
|
429
|
-
"type": "string",
|
|
430
|
-
"description": "Optional relative directory filter: topics, journal, or a subdirectory of either."
|
|
431
|
-
},
|
|
432
|
-
"status": {
|
|
433
|
-
"type": "string",
|
|
434
|
-
"enum": [
|
|
435
|
-
"active",
|
|
436
|
-
"locked",
|
|
437
|
-
"archived",
|
|
438
|
-
"any"
|
|
439
|
-
],
|
|
440
|
-
"description": "Card status filter. Default active+locked; \"any\" includes archived."
|
|
441
|
-
}
|
|
442
|
-
},
|
|
443
|
-
"hasExecute": true
|
|
444
|
-
},
|
|
445
|
-
{
|
|
446
|
-
"name": "session_live_update",
|
|
447
|
-
"description": "Write or patch this session's row in the live registry (<memoryRoot>/.longlive/live/<sessionId>.json). state is required: idle | running | waiting | blocked | stale. Omitted optional fields keep their previous value, except blocked_on, which is cleared whenever state is not \"blocked\". pid and host are always the calling process and machine; startedAt is preserved. goal is cut to 80 characters, queued to 200 items of 300 characters each, and last_action.detail to 500 characters; the result reports every cut (goalTruncated / queuedTruncated / lastActionDetailTruncated). The file is written tmp -> rename with a read-back, so a crash never leaves half a JSON. If a directory or symlink occupies the row path, the write is refused up front with E_LIVE_ROW_BLOCKED instead of failing late in rename. Pass sessionId only to write another session's row; by default the host's current session is used.",
|
|
448
|
-
"parameters": {
|
|
449
|
-
"sessionId": {
|
|
450
|
-
"type": "string",
|
|
451
|
-
"description": "Optional session id; defaults to the host's current session id."
|
|
452
|
-
},
|
|
453
|
-
"state": {
|
|
454
|
-
"type": "string",
|
|
455
|
-
"enum": [
|
|
456
|
-
"idle",
|
|
457
|
-
"running",
|
|
458
|
-
"waiting",
|
|
459
|
-
"blocked",
|
|
460
|
-
"stale"
|
|
461
|
-
],
|
|
462
|
-
"description": "Required writer-declared state. dead/corrupt are computed by readers and cannot be written."
|
|
463
|
-
},
|
|
464
|
-
"turn": {
|
|
465
|
-
"type": "integer",
|
|
466
|
-
"description": "Current turn number (integer >= 0, default keeps the previous value or 0)."
|
|
467
|
-
},
|
|
468
|
-
"goal": {
|
|
469
|
-
"type": "string",
|
|
470
|
-
"description": "What this session is doing; stored at most 80 characters (longer input is truncated and flagged)."
|
|
471
|
-
},
|
|
472
|
-
"blocked_on": {
|
|
473
|
-
"type": "string",
|
|
474
|
-
"description": "What the session is waiting on. Only kept while state is \"blocked\"."
|
|
475
|
-
},
|
|
476
|
-
"queued": {
|
|
477
|
-
"type": "array",
|
|
478
|
-
"items": {
|
|
479
|
-
"type": "string"
|
|
480
|
-
},
|
|
481
|
-
"description": "Queued work items (strings); replaces the previous queue."
|
|
482
|
-
},
|
|
483
|
-
"ttlMs": {
|
|
484
|
-
"type": "integer",
|
|
485
|
-
"description": "Heartbeat lifetime in ms (integer 1000..86400000, default 60000). Older than 2x this is stale."
|
|
486
|
-
},
|
|
487
|
-
"last_action": {
|
|
488
|
-
"type": "object",
|
|
489
|
-
"additionalProperties": false,
|
|
490
|
-
"properties": {
|
|
491
|
-
"at": {
|
|
492
|
-
"type": "string",
|
|
493
|
-
"description": "ISO timestamp; defaults to now."
|
|
494
|
-
},
|
|
495
|
-
"kind": {
|
|
496
|
-
"type": "string",
|
|
497
|
-
"description": "Short action kind, e.g. \"edit\" or \"tool\"."
|
|
498
|
-
},
|
|
499
|
-
"detail": {
|
|
500
|
-
"type": "string",
|
|
501
|
-
"description": "Short human-readable detail."
|
|
502
|
-
}
|
|
503
|
-
},
|
|
504
|
-
"description": "Last action {at, kind, detail}; defaults to now/create or now/update."
|
|
505
|
-
}
|
|
506
|
-
},
|
|
507
|
-
"hasExecute": true
|
|
508
|
-
},
|
|
509
|
-
{
|
|
510
|
-
"name": "session_live_list",
|
|
511
|
-
"description": "List the live registry (<memoryRoot>/.longlive/live) with a computed effectiveState for every row. Liveness is heartbeat-first: a heartbeat within one ttlMs is running regardless of pid (pid is the writer's, not the session's); older than 2x ttlMs is stale; older than 4x ttlMs, or same-host with a pid that definitively no longer exists, is dead; a file that cannot be parsed or has the wrong shape is corrupt (listed, never thrown). Other hosts' pids are never probed, so remote rows age purely by heartbeat and can be stale or dead but are never treated as dead by pid. dead rows are hidden unless includeDead:true; the result always reports hiddenDead and per-state counts. Orphan tmp files are ignored by the list.",
|
|
512
|
-
"parameters": {
|
|
513
|
-
"includeDead": {
|
|
514
|
-
"type": "boolean",
|
|
515
|
-
"description": "Default false: hide rows whose same-host pid no longer exists."
|
|
516
|
-
}
|
|
517
|
-
},
|
|
518
|
-
"hasExecute": true
|
|
519
|
-
},
|
|
520
|
-
{
|
|
521
|
-
"name": "session_live_get",
|
|
522
|
-
"description": "Read one row of the live registry by sessionId, with the same computed effectiveState as session_live_list (dead / stale / corrupt included). sessionId must already be canonical (lowercase): a case or whitespace alias throws E_SESSION_ID_NOT_CANONICAL with the canonical id in error.canonical, because NTFS maps aliases to one file and a silent lookup cannot say which session was read. A symlinked row is refused rather than followed. A missing row returns ok:false status:\"absent\" instead of failing; a row that cannot be parsed throws E_LIVE_CORRUPT.",
|
|
523
|
-
"parameters": {
|
|
524
|
-
"sessionId": {
|
|
525
|
-
"type": "string",
|
|
526
|
-
"description": "Session id whose row to read. Required."
|
|
527
|
-
}
|
|
528
|
-
},
|
|
529
|
-
"hasExecute": true
|
|
530
|
-
},
|
|
531
|
-
{
|
|
532
|
-
"name": "session_live_prune",
|
|
533
|
-
"description": "Clean the live registry. Row candidates are dead rows from this host (heartbeat older than 4x ttlMs, or same-host pid definitively gone), or corrupt rows without another host's stamp. Before unlinking, each candidate is re-read and re-judged: it is deleted only if it is STILL dead/corrupt AND its bytes did not change; otherwise it is returned under skipped. A row carrying blocked_on is never auto-deleted (skipped), and every deleted/skipped row keeps blocked_on, queued and startedAt in the result. Remote rows are never deleted: a merely dead remote row is left alone, and a corrupt row whose bytes still name a remote host is skipped too (host unknown is the only corrupt case prune may remove). Also reports (and with confirm removes) orphan *.tmp-* files older than one hour and empty directory placeholders; non-empty directories and symlinks are reported only. Default is dry-run (candidates, wouldDelete, skipped; deletes nothing); a real delete requires confirm:\"PRUNE\". dryRun:false without the confirm word throws E_CONFIRM_REQUIRED.",
|
|
534
|
-
"parameters": {
|
|
535
|
-
"dryRun": {
|
|
536
|
-
"type": "boolean",
|
|
537
|
-
"description": "Default true (preview only). false with confirm:\"PRUNE\" really deletes."
|
|
538
|
-
},
|
|
539
|
-
"confirm": {
|
|
540
|
-
"type": "string",
|
|
541
|
-
"description": "Pass \"PRUNE\" to actually delete the previewed candidates."
|
|
542
|
-
}
|
|
543
|
-
},
|
|
544
|
-
"hasExecute": true
|
|
545
|
-
}
|
|
546
|
-
],
|
|
547
|
-
"hooks": [
|
|
548
|
-
{
|
|
549
|
-
"name": "session/event",
|
|
550
|
-
"prepend": false,
|
|
551
|
-
"priority": null
|
|
552
|
-
}
|
|
553
|
-
],
|
|
554
|
-
"warnings": [],
|
|
555
|
-
"infos": []
|
|
556
|
-
}
|