pi-smart-compact 10.1.4 → 10.2.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 +53 -0
- package/dist/app/anchor-cache.d.ts +3 -1
- package/dist/app/anchor-cache.d.ts.map +1 -1
- package/dist/app/context-attention.d.ts +26 -0
- package/dist/app/context-attention.d.ts.map +1 -0
- package/dist/constants.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +98 -4
- package/dist/rtk.js +1 -1
- package/docs/configuration.md +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,59 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [10.2.0] - 2026-10-05
|
|
6
|
+
|
|
7
|
+
### Release approval
|
|
8
|
+
|
|
9
|
+
- Minor release approved by the release owner after the deterministic gates
|
|
10
|
+
on the exact candidate. No version-specific applied-canary cohort or live
|
|
11
|
+
provider run exists for `10.2.0`; the feature is evidenced by unit tests
|
|
12
|
+
only. The note is gated by `Navigation guide` (`contextGuidanceEnabled`)
|
|
13
|
+
and turns off with it.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **Context attention.** Context pressure used to reach the model only through
|
|
18
|
+
the human status line and `smart_context status` results, so the anchor,
|
|
19
|
+
checkpoint/rewind, trim and compaction tools sat idle until a person asked
|
|
20
|
+
for them. The extension now sends the model one short note when usage
|
|
21
|
+
enters the cleanup band and one more at the compaction band, naming only
|
|
22
|
+
the actions available right now: `smart_navigation anchor` (with the lazy
|
|
23
|
+
`smart_tools` load step when needed), `smart_context checkpoint`/`rewind`
|
|
24
|
+
and `trim` only when history edits are possible on this model (signed
|
|
25
|
+
Anthropic thinking blocks them), plus whether automatic compaction will
|
|
26
|
+
prepare. Mid-turn the note rides along with the next tool batch; at a turn
|
|
27
|
+
end a cleanup note waits for the next prompt and a compaction note is
|
|
28
|
+
skipped under auto-trigger because settled compaction runs first. One note
|
|
29
|
+
per band per session, re-armed once pressure clears; the note is a tail
|
|
30
|
+
message, so the cached prefix is untouched. Gated by `Navigation guide`
|
|
31
|
+
(`contextGuidanceEnabled`), tool loading and agent tool access.
|
|
32
|
+
|
|
33
|
+
## [10.1.5] - 2026-10-05
|
|
34
|
+
|
|
35
|
+
### Release approval
|
|
36
|
+
|
|
37
|
+
- Patch release approved by the release owner after the deterministic gates
|
|
38
|
+
on the exact candidate. No version-specific applied-canary cohort or live
|
|
39
|
+
provider run exists for `10.1.5`; the fix is evidenced by unit tests and
|
|
40
|
+
offline replay of a recorded session's cache usage only.
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
|
|
44
|
+
- **Anchor prompt cache no longer evicts the rolling cache marker on OAuth
|
|
45
|
+
payloads.** pi-ai places `cache_control` on both OAuth system blocks (the
|
|
46
|
+
Claude Code identity line and the system prompt), so an Anthropic request
|
|
47
|
+
already carries four breakpoints: identity, system prompt, tools, rolling
|
|
48
|
+
tail. Adding the anchor marker made five, and the limit enforcement dropped
|
|
49
|
+
the first foreign message marker, which was the rolling tail. From the
|
|
50
|
+
first turn after an anchor every request then read only the prefix up to
|
|
51
|
+
the anchor and wrote nothing: `cacheWrite` stayed 0 while uncached input
|
|
52
|
+
grew turn by turn (a recorded session fell from 99% to 40% cache hits and
|
|
53
|
+
stayed there through a compaction that kept the anchor). The rolling tail
|
|
54
|
+
is now never an eviction candidate; the redundant identity marker goes
|
|
55
|
+
first, then the tools marker, both of which only cover prefixes of the
|
|
56
|
+
system-prompt marker. API-key payloads (one system marker) were unaffected.
|
|
57
|
+
|
|
5
58
|
## [10.1.4] - 2026-10-02
|
|
6
59
|
|
|
7
60
|
### Release approval
|
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
* reply after N yet) N's prefix has never been written. The previous anchor M
|
|
17
17
|
* keeps a marker too, [system, tools, M, N], so the prefix through M is read
|
|
18
18
|
* and only (M, N] is written. The bridge uses a free slot or displaces a
|
|
19
|
-
* foreign
|
|
19
|
+
* redundant foreign marker (see `evictable`); it never displaces the rolling
|
|
20
|
+
* tail, which is what advances the cache every turn (pi-ai's OAuth layout
|
|
21
|
+
* already carries four markers: identity, system prompt, tools, tail).
|
|
20
22
|
*
|
|
21
23
|
* TTL follows the payload: a `1h` marker (Pi long retention) makes the anchor
|
|
22
24
|
* `1h` and rolling markers after it `5m`; otherwise markers stay default.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anchor-cache.d.ts","sourceRoot":"","sources":["../../src/app/anchor-cache.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"anchor-cache.d.ts","sourceRoot":"","sources":["../../src/app/anchor-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,iCAAiC,CAAC;AACtF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,KAAK,iBAAiB,GAAG,IAAI,CAAC,aAAa,EAAE,0BAA0B,GAAG,2BAA2B,CAAC,CAAC;AA6CvG,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,EAC5B,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;CAAE,GACxC,IAAI,CAEN"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context attention: one short note to the model when context pressure enters
|
|
3
|
+
* a band, naming only the actions that are available right now.
|
|
4
|
+
*
|
|
5
|
+
* Pressure used to reach the model only through the human status line and
|
|
6
|
+
* `smart_context status` results, so the navigation, history and compaction
|
|
7
|
+
* tools sat idle until a person asked for them. The note rides along with the
|
|
8
|
+
* next tool batch (steer) during a turn; when a turn ends in the cleanup band
|
|
9
|
+
* it waits for the next prompt instead. One note per band per session,
|
|
10
|
+
* re-armed once pressure clears (compaction, trim, rewind). The note is a
|
|
11
|
+
* tail custom message, so the cached prefix is untouched.
|
|
12
|
+
*/
|
|
13
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
14
|
+
import type { CompactConfig } from "../types.ts";
|
|
15
|
+
export declare const ATTENTION_CUSTOM_TYPE = "smart-compact-attention";
|
|
16
|
+
type AttentionConfig = Pick<CompactConfig, "contextNavigationEnabled" | "contextGuidanceEnabled" | "toolLoading" | "autoTrigger" | "minContextPercent" | "prepareContextPercent" | "maxContextTokens">;
|
|
17
|
+
export interface ContextAttentionDeps {
|
|
18
|
+
config: () => AttentionConfig;
|
|
19
|
+
/** Agent-driven context changes are permitted and nothing (pivot, running compaction) takes priority. */
|
|
20
|
+
canAgentAct: (ctx: ExtensionContext) => boolean;
|
|
21
|
+
/** A lazy group can still be loaded through `smart_tools`. */
|
|
22
|
+
reachable: (group: "navigation" | "history") => boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare function registerContextAttention(pi: Pick<ExtensionAPI, "on" | "sendMessage" | "getActiveTools">, deps: ContextAttentionDeps): void;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=context-attention.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-attention.d.ts","sourceRoot":"","sources":["../../src/app/context-attention.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEtF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,eAAO,MAAM,qBAAqB,4BAA4B,CAAC;AAK/D,KAAK,eAAe,GAAG,IAAI,CAAC,aAAa,EACvC,0BAA0B,GAAG,wBAAwB,GAAG,aAAa,GAAG,aAAa,GACnF,mBAAmB,GAAG,uBAAuB,GAAG,kBAAkB,CAAC,CAAC;AAExE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,eAAe,CAAC;IAC9B,yGAAyG;IACzG,WAAW,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,OAAO,CAAC;IAChD,8DAA8D;IAC9D,SAAS,EAAE,CAAC,KAAK,EAAE,YAAY,GAAG,SAAS,KAAK,OAAO,CAAC;CACzD;AAED,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,aAAa,GAAG,gBAAgB,CAAC,EAC/D,IAAI,EAAE,oBAAoB,GACzB,IAAI,CAoCN"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { CompressionProfile, ProfileConfig } from "./types.ts";
|
|
|
8
8
|
* `package.json#version`. Do not hand-edit this line for releases; bump
|
|
9
9
|
* package.json and run `bun run sync-version`.
|
|
10
10
|
*/
|
|
11
|
-
export declare const VERSION = "10.
|
|
11
|
+
export declare const VERSION = "10.2.0";
|
|
12
12
|
/**
|
|
13
13
|
* Opt-in components that are not installed with the extension: optional peer
|
|
14
14
|
* dependencies in package.json, pinned to the versions the release audit
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEN,KAAK,YAAY,EAEjB,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEN,KAAK,YAAY,EAEjB,MAAM,iCAAiC,CAAC;AAmEzC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAyDtE,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAAE,EAAE,YAAY,QAomB7D"}
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "@earendil-works/pi-coding-agent";
|
|
6
6
|
|
|
7
7
|
// src/constants.ts
|
|
8
|
-
var VERSION = "10.
|
|
8
|
+
var VERSION = "10.2.0";
|
|
9
9
|
var OPTIONAL_COMPONENTS = {
|
|
10
10
|
mnemopi: { name: "@oh-my-pi/pi-mnemopi", version: "18.3.1", enables: "Mnemopi memory store" },
|
|
11
11
|
bun: { name: "bun", version: "1.4.2", enables: "Mnemopi worker runtime when no Bun 1.3.14+ is on PATH" },
|
|
@@ -16807,6 +16807,85 @@ function createSettledAutoTrigger(options = {}) {
|
|
|
16807
16807
|
return { request, noteCompaction, clear };
|
|
16808
16808
|
}
|
|
16809
16809
|
|
|
16810
|
+
// src/app/context-attention.ts
|
|
16811
|
+
var ATTENTION_CUSTOM_TYPE = "smart-compact-attention";
|
|
16812
|
+
var CONTEXT_TOOL_NAME = "smart_context";
|
|
16813
|
+
var LOADER_TOOL_NAME = "smart_tools";
|
|
16814
|
+
function registerContextAttention(pi, deps) {
|
|
16815
|
+
let noted = null;
|
|
16816
|
+
const clear = () => {
|
|
16817
|
+
noted = null;
|
|
16818
|
+
};
|
|
16819
|
+
pi.on("session_start", clear);
|
|
16820
|
+
pi.on("session_before_switch", clear);
|
|
16821
|
+
pi.on("session_before_fork", clear);
|
|
16822
|
+
pi.on("session_tree", clear);
|
|
16823
|
+
pi.on("message_end", (event, ctx) => {
|
|
16824
|
+
const message = event.message;
|
|
16825
|
+
if (message.role !== "assistant")
|
|
16826
|
+
return;
|
|
16827
|
+
const settings = deps.config();
|
|
16828
|
+
if (!settings.contextNavigationEnabled || !settings.contextGuidanceEnabled || settings.toolLoading === "off")
|
|
16829
|
+
return;
|
|
16830
|
+
const sessionId = resolveSessionId(ctx);
|
|
16831
|
+
const pressure = contextPressure(ctx, settings);
|
|
16832
|
+
const band = pressure.compaction ? "compaction" : pressure.cleanup ? "cleanup" : null;
|
|
16833
|
+
if (!band) {
|
|
16834
|
+
if (noted?.sessionId === sessionId)
|
|
16835
|
+
noted = null;
|
|
16836
|
+
return;
|
|
16837
|
+
}
|
|
16838
|
+
if (noted?.sessionId === sessionId && (noted.band === band || noted.band === "compaction"))
|
|
16839
|
+
return;
|
|
16840
|
+
if (message.content.some((block) => block.type === "toolCall" && (block.name === NAVIGATION_TOOL_NAME || block.name === CONTEXT_TOOL_NAME)))
|
|
16841
|
+
return;
|
|
16842
|
+
const midTurn = message.stopReason === "toolUse";
|
|
16843
|
+
if (!midTurn && band === "compaction" && settings.autoTrigger)
|
|
16844
|
+
return;
|
|
16845
|
+
if (!deps.canAgentAct(ctx))
|
|
16846
|
+
return;
|
|
16847
|
+
const active = new Set(pi.getActiveTools());
|
|
16848
|
+
const content = renderAttention(band, pressure.percent, settings, ctx, active, deps.reachable);
|
|
16849
|
+
if (!content)
|
|
16850
|
+
return;
|
|
16851
|
+
noted = { sessionId, band };
|
|
16852
|
+
pi.sendMessage({ customType: ATTENTION_CUSTOM_TYPE, content, display: true, details: { band, percent: pressure.percent } }, { deliverAs: midTurn ? "steer" : "nextTurn" });
|
|
16853
|
+
});
|
|
16854
|
+
}
|
|
16855
|
+
function renderAttention(band, percent, settings, ctx, active, reachable) {
|
|
16856
|
+
const lines = [];
|
|
16857
|
+
const load = (group, tool) => active.has(tool) ? "" : reachable(group) && active.has(LOADER_TOOL_NAME) ? ` Load it first: ${LOADER_TOOL_NAME} load ${group}.` : null;
|
|
16858
|
+
const navigation = load("navigation", NAVIGATION_TOOL_NAME);
|
|
16859
|
+
const history = load("history", CONTEXT_TOOL_NAME);
|
|
16860
|
+
if (navigation !== null) {
|
|
16861
|
+
lines.push((band === "compaction" ? `- Anchor now: ${NAVIGATION_TOOL_NAME} anchor with a name and a concise handoff (done / in progress / next step). The summary starts from it and the prompt cache stays warm up to it.` : `- Finishing a unit of work? ${NAVIGATION_TOOL_NAME} anchor with a concise handoff; safe cleanup is queued automatically and the prefix up to the anchor stays cached.`) + navigation);
|
|
16862
|
+
}
|
|
16863
|
+
if (history !== null) {
|
|
16864
|
+
const branch = ctx.sessionManager.getBranch();
|
|
16865
|
+
let trimmable = 0;
|
|
16866
|
+
let blocked = false;
|
|
16867
|
+
try {
|
|
16868
|
+
const plan = planContextTrim(branch, inspectContext(branch, resolveSessionId(ctx)).checkpoint?.originId, { readerApi: ctx.model?.api });
|
|
16869
|
+
blocked = Boolean(plan.blockedReason);
|
|
16870
|
+
trimmable = plan.entries.filter((entry) => entry.type === "context_edit").length;
|
|
16871
|
+
} catch {
|
|
16872
|
+
blocked = true;
|
|
16873
|
+
}
|
|
16874
|
+
if (!blocked) {
|
|
16875
|
+
if (trimmable > 0)
|
|
16876
|
+
lines.push(`- ${CONTEXT_TOOL_NAME} trim: ${trimmable} archived tool output${trimmable === 1 ? "" : "s"} eligible now.${history}`);
|
|
16877
|
+
lines.push(`- Starting a large read-only detour? ${CONTEXT_TOOL_NAME} checkpoint first, then rewind(report) when done keeps the findings and drops the research.${trimmable > 0 ? "" : history}`);
|
|
16878
|
+
}
|
|
16879
|
+
}
|
|
16880
|
+
if (!lines.length)
|
|
16881
|
+
return null;
|
|
16882
|
+
const where = percent === null ? "" : ` ${Math.round(percent)}% of the policy window`;
|
|
16883
|
+
const head = band === "compaction" ? `Context attention:${where} (compaction band). ` + (settings.autoTrigger ? "Compaction prepares now and applies when the turn settles." : "Automatic compaction is off here; the user runs /smart-compact.") : `Context attention:${where} (cleanup band). ` + (settings.autoTrigger ? `Automatic compaction prepares at ${settings.minContextPercent}%.` : "Automatic compaction is off here.");
|
|
16884
|
+
return `${head}
|
|
16885
|
+
${lines.join(`
|
|
16886
|
+
`)}`;
|
|
16887
|
+
}
|
|
16888
|
+
|
|
16810
16889
|
// src/app/host-cache-ledger.ts
|
|
16811
16890
|
var FOREIGN_REBUILD_WARN_COUNT = 3;
|
|
16812
16891
|
var num = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
@@ -24685,8 +24764,18 @@ function transitionBridge(payload, anchors, anchorLoc) {
|
|
|
24685
24764
|
}
|
|
24686
24765
|
function bridgeFits(payload) {
|
|
24687
24766
|
const markers = listMarkers(payload);
|
|
24688
|
-
|
|
24689
|
-
|
|
24767
|
+
return markers.length - evictable(markers).length < MARKER_LIMIT;
|
|
24768
|
+
}
|
|
24769
|
+
function evictable(markers) {
|
|
24770
|
+
const foreign = (list) => list.filter((m) => !m.owned);
|
|
24771
|
+
const messages = markers.filter((m) => m.section === "messages");
|
|
24772
|
+
const system = markers.filter((m) => m.section === "system");
|
|
24773
|
+
return [
|
|
24774
|
+
...foreign(messages.slice(0, -1)),
|
|
24775
|
+
...foreign(system.slice(0, -1)),
|
|
24776
|
+
...foreign(markers.filter((m) => m.section === "tools")),
|
|
24777
|
+
...foreign(system.slice(-1))
|
|
24778
|
+
];
|
|
24690
24779
|
}
|
|
24691
24780
|
function setMarker(payload, ref, control) {
|
|
24692
24781
|
const block = payload.messages[ref.msgIdx].content[ref.blockIdx];
|
|
@@ -24748,7 +24837,7 @@ function countMarkers(payload) {
|
|
|
24748
24837
|
function enforceMarkerLimit(payload) {
|
|
24749
24838
|
let markers = listMarkers(payload);
|
|
24750
24839
|
while (markers.length > MARKER_LIMIT) {
|
|
24751
|
-
const target =
|
|
24840
|
+
const target = evictable(markers)[0];
|
|
24752
24841
|
if (!target)
|
|
24753
24842
|
break;
|
|
24754
24843
|
delete blockAt(payload, target).cache_control;
|
|
@@ -25013,6 +25102,11 @@ function smartCompactExtension(pi) {
|
|
|
25013
25102
|
hostCache.noteCacheWarm(at);
|
|
25014
25103
|
}
|
|
25015
25104
|
});
|
|
25105
|
+
registerContextAttention(pi, {
|
|
25106
|
+
config: automaticConfig,
|
|
25107
|
+
canAgentAct: (ctx) => policy.snapshot().agentToolAccess !== "disabled" && !pivotQueued(ctx) && !isRunning.isSessionActive(resolveSessionId(ctx)),
|
|
25108
|
+
reachable: (group) => toolExposure.reachable(group)
|
|
25109
|
+
});
|
|
25016
25110
|
registerSmartCompactCommand(pi, {
|
|
25017
25111
|
pendingRef,
|
|
25018
25112
|
runLock: isRunning,
|
package/dist/rtk.js
CHANGED
|
@@ -198,7 +198,7 @@ class SecretScrubber {
|
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
// src/constants.ts
|
|
201
|
-
var VERSION = "10.
|
|
201
|
+
var VERSION = "10.2.0";
|
|
202
202
|
var OPTIONAL_COMPONENTS = {
|
|
203
203
|
mnemopi: { name: "@oh-my-pi/pi-mnemopi", version: "18.3.1", enables: "Mnemopi memory store" },
|
|
204
204
|
bun: { name: "bun", version: "1.4.2", enables: "Mnemopi worker runtime when no Bun 1.3.14+ is on PATH" },
|
package/docs/configuration.md
CHANGED
|
@@ -454,7 +454,7 @@ Settings → **Agent tools & navigation**.
|
|
|
454
454
|
| `contextPivotEnabled` | `Return to an anchor` | `true` | Returning to an anchor on a new branch with a required carryover. |
|
|
455
455
|
| `contextAnchorCacheEnabled` | `Anchor prompt cache` | `true` | Anthropic models: keeps a prompt-cache marker on the newest anchor. |
|
|
456
456
|
| `contextAnchorStatusEnabled` | `Anchor status` | `true` | Shows the newest anchor on this branch in Pi's footer; display only. |
|
|
457
|
-
| `contextGuidanceEnabled` | `Navigation guide` | `true` | Lets you or the agent open the navigation guide on request; it is never added to a request otherwise. |
|
|
457
|
+
| `contextGuidanceEnabled` | `Navigation guide` | `true` | Lets you or the agent open the navigation guide on request; it is never added to a request otherwise. Also enables context attention: one short note to the model when context usage enters the cleanup band and again at the compaction band, naming only the context tools available right now (anchor; checkpoint/rewind and trim when history edits are possible). Re-armed once pressure clears. |
|
|
458
458
|
|
|
459
459
|
Group permissions apply in both `lazy` and `eager` modes: `compaction` follows
|
|
460
460
|
`agentToolAccess`, `memory` needs `contextGraphEnabled` or a non-local
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-smart-compact",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.2.0",
|
|
4
4
|
"description": "Pi Continuity — context hygiene and session continuity for Pi Coding Agent: recoverable cleanup, checkpoints, memory and verified compaction.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "bun@1.4.2",
|