@chengchenccc/oh-my-agent 0.2.0-rc.2 → 0.2.0-rc.4
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.md +11 -6
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +9 -2
- package/dist/cli/gateway-commands.d.ts.map +1 -1
- package/dist/cli/gateway-commands.js +35 -5
- package/dist/cli/initial-input.d.ts +3 -2
- package/dist/cli/initial-input.d.ts.map +1 -1
- package/dist/core/coordination/registry.d.ts +11 -0
- package/dist/core/coordination/registry.d.ts.map +1 -1
- package/dist/core/coordination/registry.js +23 -0
- package/dist/core/gateway/artifact.d.ts +0 -1
- package/dist/core/gateway/artifact.d.ts.map +1 -1
- package/dist/core/gateway/artifact.js +1 -1
- package/dist/core/goals/index.d.ts +8 -0
- package/dist/core/goals/index.d.ts.map +1 -0
- package/dist/core/goals/index.js +7 -0
- package/dist/core/goals/runtime.d.ts +112 -0
- package/dist/core/goals/runtime.d.ts.map +1 -0
- package/dist/core/goals/runtime.js +241 -0
- package/dist/core/goals/state.d.ts +82 -0
- package/dist/core/goals/state.d.ts.map +1 -0
- package/dist/core/goals/state.js +225 -0
- package/dist/core/goals/tool.d.ts +10 -0
- package/dist/core/goals/tool.d.ts.map +1 -0
- package/dist/core/goals/tool.js +87 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +4 -3
- package/dist/core/loops/condition.d.ts +57 -0
- package/dist/core/loops/condition.d.ts.map +1 -0
- package/dist/core/loops/condition.js +153 -0
- package/dist/core/loops/index.d.ts +9 -0
- package/dist/core/loops/index.d.ts.map +1 -0
- package/dist/core/loops/index.js +8 -0
- package/dist/core/loops/limits.d.ts +43 -0
- package/dist/core/loops/limits.d.ts.map +1 -0
- package/dist/core/loops/limits.js +219 -0
- package/dist/core/loops/ralph.d.ts +37 -0
- package/dist/core/loops/ralph.d.ts.map +1 -0
- package/dist/core/loops/ralph.js +72 -0
- package/dist/core/loops/runtime.d.ts +95 -0
- package/dist/core/loops/runtime.d.ts.map +1 -0
- package/dist/core/loops/runtime.js +222 -0
- package/dist/core/memory/managed-skills.d.ts +0 -11
- package/dist/core/memory/managed-skills.d.ts.map +1 -1
- package/dist/core/memory/managed-skills.js +2 -2
- package/dist/core/memory/vector-store.d.ts +0 -1
- package/dist/core/memory/vector-store.d.ts.map +1 -1
- package/dist/core/memory/vector-store.js +0 -3
- package/dist/core/plans/index.d.ts +7 -0
- package/dist/core/plans/index.d.ts.map +1 -0
- package/dist/core/plans/index.js +6 -0
- package/dist/core/plans/prompts.d.ts +20 -0
- package/dist/core/plans/prompts.d.ts.map +1 -0
- package/dist/core/plans/prompts.js +72 -0
- package/dist/core/plans/runtime.d.ts +89 -0
- package/dist/core/plans/runtime.d.ts.map +1 -0
- package/dist/core/plans/runtime.js +170 -0
- package/dist/core/plans/state.d.ts +55 -0
- package/dist/core/plans/state.d.ts.map +1 -0
- package/dist/core/plans/state.js +88 -0
- package/dist/core/runtime/agent-loop-messages.d.ts +6 -0
- package/dist/core/runtime/agent-loop-messages.d.ts.map +1 -1
- package/dist/core/runtime/agent-loop-messages.js +40 -15
- package/dist/core/runtime/agent-loop-run.d.ts.map +1 -1
- package/dist/core/runtime/agent-loop-run.js +18 -27
- package/dist/core/runtime/agent-loop-runner.d.ts +1 -23
- package/dist/core/runtime/agent-loop-runner.d.ts.map +1 -1
- package/dist/core/runtime/agent-loop-runner.js +84 -30
- package/dist/core/runtime/agent-loop-types.d.ts +4 -0
- package/dist/core/runtime/agent-loop-types.d.ts.map +1 -1
- package/dist/core/runtime/compaction.d.ts +9 -0
- package/dist/core/runtime/compaction.d.ts.map +1 -1
- package/dist/core/runtime/compaction.js +28 -0
- package/dist/core/runtime/context-estimate.d.ts +37 -4
- package/dist/core/runtime/context-estimate.d.ts.map +1 -1
- package/dist/core/runtime/context-estimate.js +70 -0
- package/dist/core/runtime/create-runtime.d.ts +27 -5
- package/dist/core/runtime/create-runtime.d.ts.map +1 -1
- package/dist/core/runtime/create-runtime.js +22 -2
- package/dist/core/runtime/permission-classifier.d.ts.map +1 -1
- package/dist/core/runtime/permission-classifier.js +83 -12
- package/dist/core/runtime/plugin.d.ts +7 -0
- package/dist/core/runtime/plugin.d.ts.map +1 -1
- package/dist/core/runtime/plugin.js +13 -0
- package/dist/core/runtime/process-tree.d.ts +0 -9
- package/dist/core/runtime/process-tree.d.ts.map +1 -1
- package/dist/core/runtime/process-tree.js +1 -1
- package/dist/core/runtime/run-runtime.d.ts.map +1 -1
- package/dist/core/runtime/run-runtime.js +88 -49
- package/dist/core/runtime/runtime-catalog.d.ts +0 -4
- package/dist/core/runtime/runtime-catalog.d.ts.map +1 -1
- package/dist/core/runtime/runtime-catalog.js +1 -1
- package/dist/core/runtime/stream-rules.d.ts +9 -2
- package/dist/core/runtime/stream-rules.d.ts.map +1 -1
- package/dist/core/runtime/stream-rules.js +19 -5
- package/dist/core/runtime/title.d.ts +13 -1
- package/dist/core/runtime/title.d.ts.map +1 -1
- package/dist/core/runtime/title.js +51 -17
- package/dist/core/runtime/tool-pruning.d.ts.map +1 -1
- package/dist/core/runtime/tool-pruning.js +8 -16
- package/dist/core/session/session-file.d.ts +91 -5
- package/dist/core/session/session-file.d.ts.map +1 -1
- package/dist/core/session/session-file.js +206 -24
- package/dist/core/session/session-loop.d.ts +3 -1
- package/dist/core/session/session-loop.d.ts.map +1 -1
- package/dist/core/session/session-loop.js +8 -4
- package/dist/core/settings/project-settings.d.ts +63 -9
- package/dist/core/settings/project-settings.d.ts.map +1 -1
- package/dist/core/settings/project-settings.js +43 -2
- package/dist/core/settings/workspace-context.js +4 -4
- package/dist/core/store/in-memory-session-store.d.ts.map +1 -1
- package/dist/core/store/in-memory-session-store.js +3 -2
- package/dist/core/store/session-store.contract.test-helper.d.ts +7 -5
- package/dist/core/store/session-store.contract.test-helper.d.ts.map +1 -1
- package/dist/core/store/session-store.contract.test-helper.js +7 -5
- package/dist/core/store/session-store.d.ts +4 -2
- package/dist/core/store/session-store.d.ts.map +1 -1
- package/dist/core/store/session-store.js +4 -2
- package/dist/core/tools/ask-question.d.ts.map +1 -1
- package/dist/core/tools/ask-question.js +51 -5
- package/dist/core/tools/bash-pty.d.ts +13 -4
- package/dist/core/tools/bash-pty.d.ts.map +1 -1
- package/dist/core/tools/bash-pty.js +15 -8
- package/dist/core/tools/bash-sandbox.d.ts +1 -1
- package/dist/core/tools/bash.d.ts +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +18 -8
- package/dist/core/tools/browser.d.ts +54 -0
- package/dist/core/tools/browser.d.ts.map +1 -1
- package/dist/core/tools/browser.js +138 -1
- package/dist/core/tools/file-fingerprint.d.ts +24 -0
- package/dist/core/tools/file-fingerprint.d.ts.map +1 -0
- package/dist/core/tools/file-fingerprint.js +61 -0
- package/dist/core/tools/file-tools.d.ts +26 -0
- package/dist/core/tools/file-tools.d.ts.map +1 -1
- package/dist/core/tools/file-tools.js +113 -17
- package/dist/core/tools/index.d.ts +2 -0
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +1 -0
- package/dist/core/tools/mcp-mount.d.ts +1 -1
- package/dist/core/tools/mcp-mount.d.ts.map +1 -1
- package/dist/core/tools/mcp-mount.js +72 -26
- package/dist/core/tools/url-guard.d.ts +15 -0
- package/dist/core/tools/url-guard.d.ts.map +1 -1
- package/dist/core/tools/url-guard.js +54 -14
- package/dist/core/tools/web-ports-std.d.ts.map +1 -1
- package/dist/core/tools/web-ports-std.js +5 -2
- package/dist/modes/print-mode.d.ts +3 -2
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +2 -2
- package/dist/modes/shared.d.ts +12 -0
- package/dist/modes/shared.d.ts.map +1 -1
- package/dist/modes/shared.js +23 -6
- package/dist/modes/tui/agent-status.d.ts +20 -0
- package/dist/modes/tui/agent-status.d.ts.map +1 -0
- package/dist/modes/tui/agent-status.js +35 -0
- package/dist/modes/tui/ask-panel.d.ts +166 -0
- package/dist/modes/tui/ask-panel.d.ts.map +1 -0
- package/dist/modes/tui/ask-panel.js +888 -0
- package/dist/modes/tui/pty-console.d.ts +3 -0
- package/dist/modes/tui/pty-console.d.ts.map +1 -1
- package/dist/modes/tui/pty-console.js +19 -0
- package/dist/modes/tui/settings-overlay.d.ts +19 -0
- package/dist/modes/tui/settings-overlay.d.ts.map +1 -1
- package/dist/modes/tui/settings-overlay.js +46 -10
- package/dist/modes/tui/tui-commands-session.d.ts.map +1 -1
- package/dist/modes/tui/tui-commands-session.js +20 -6
- package/dist/modes/tui/tui-commands.d.ts +44 -3
- package/dist/modes/tui/tui-commands.d.ts.map +1 -1
- package/dist/modes/tui/tui-commands.js +380 -6
- package/dist/modes/tui/tui-components.d.ts +10 -0
- package/dist/modes/tui/tui-components.d.ts.map +1 -1
- package/dist/modes/tui/tui-components.js +26 -0
- package/dist/modes/tui/tui-format.d.ts +53 -4
- package/dist/modes/tui/tui-format.d.ts.map +1 -1
- package/dist/modes/tui/tui-format.js +137 -42
- package/dist/modes/tui/tui-frame-provider.d.ts +11 -3
- package/dist/modes/tui/tui-frame-provider.d.ts.map +1 -1
- package/dist/modes/tui/tui-frame-provider.js +14 -5
- package/dist/modes/tui/tui-interactive.d.ts.map +1 -1
- package/dist/modes/tui/tui-interactive.js +14 -0
- package/dist/modes/tui/tui-io.d.ts.map +1 -1
- package/dist/modes/tui/tui-io.js +150 -55
- package/dist/modes/tui/tui-mode.d.ts.map +1 -1
- package/dist/modes/tui/tui-mode.js +428 -23
- package/dist/modes/tui/tui-overlays.d.ts +6 -10
- package/dist/modes/tui/tui-overlays.d.ts.map +1 -1
- package/dist/modes/tui/tui-overlays.js +0 -43
- package/dist/modes/tui/tui-render.d.ts +10 -0
- package/dist/modes/tui/tui-render.d.ts.map +1 -1
- package/dist/modes/tui/tui-render.js +73 -38
- package/dist/modes/tui/tui-seam.d.ts +28 -6
- package/dist/modes/tui/tui-seam.d.ts.map +1 -1
- package/dist/modes/tui/tui-slash.d.ts.map +1 -1
- package/dist/modes/tui/tui-slash.js +3 -1
- package/dist/modes/tui/tui-tool-render.d.ts +14 -1
- package/dist/modes/tui/tui-tool-render.d.ts.map +1 -1
- package/dist/modes/tui/tui-tool-render.js +158 -50
- package/dist/modes/tui/tui-transcript-reconciler.d.ts +4 -0
- package/dist/modes/tui/tui-transcript-reconciler.d.ts.map +1 -1
- package/dist/modes/tui/tui-transcript-reconciler.js +12 -2
- package/dist/modes/tui/view-state.d.ts.map +1 -1
- package/dist/modes/tui/view-state.js +4 -1
- package/dist/protocol/transport.d.ts +10 -0
- package/dist/protocol/transport.d.ts.map +1 -1
- package/dist/protocol/transport.js +1 -0
- package/package.json +11 -11
|
@@ -44,36 +44,50 @@ export function isLowSignalTitleInput(message) {
|
|
|
44
44
|
return tokens.every((t) => FILLER_TOKENS.has(t) || /^\d+$/.test(t));
|
|
45
45
|
}
|
|
46
46
|
// ── Prompt (XML tag format + few-shot) ───────────────────────
|
|
47
|
-
const TITLE_SYSTEM_PROMPT = `Write a 3-7 word title for the task.
|
|
47
|
+
const TITLE_SYSTEM_PROMPT = `Write a 3-7 word title and a one-sentence summary for the task.
|
|
48
48
|
|
|
49
|
-
Answer with only
|
|
50
|
-
|
|
49
|
+
Answer with only these two tags, nothing before or after:
|
|
50
|
+
<title>the title</title>
|
|
51
|
+
<summary>one sentence on what the user wants and where it stands</summary>
|
|
52
|
+
If there is no concrete task (greeting, small talk, acknowledgment), output exactly:
|
|
53
|
+
<title>none</title>
|
|
54
|
+
<summary>none</summary>
|
|
51
55
|
Capitalize only the first word and proper names.
|
|
52
56
|
|
|
53
57
|
Examples:
|
|
54
58
|
User: the login button is broken on mobile, can you fix?
|
|
55
59
|
<title>Fix login button on mobile</title>
|
|
60
|
+
<summary>The mobile login button is unresponsive; the fix has not started yet.</summary>
|
|
56
61
|
|
|
57
62
|
User: refactor error handling in the API client
|
|
58
63
|
<title>Refactor API error handling</title>
|
|
64
|
+
<summary>Reworking the API client's error handling onto typed errors.</summary>
|
|
59
65
|
|
|
60
66
|
User: hey
|
|
61
|
-
<title>none</title
|
|
67
|
+
<title>none</title>
|
|
68
|
+
<summary>none</summary>`;
|
|
62
69
|
// ── Normalization (robust extraction) ────────────────────────
|
|
63
70
|
const MAX_TITLE_CHARS = 80;
|
|
64
71
|
const MAX_TITLE_WORDS = 12;
|
|
72
|
+
const MAX_SUMMARY_CHARS = 240;
|
|
65
73
|
const NO_TITLE_SENTINELS = new Set(["none", "(无)", "无"]);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// Strip XML tags if present
|
|
71
|
-
const title = firstLine
|
|
74
|
+
const TITLE_TAG = /<title>([\s\S]*?)<\/title>/i;
|
|
75
|
+
const SUMMARY_TAG = /<summary>([\s\S]*?)<\/summary>/i;
|
|
76
|
+
function stripTitleDecoration(raw) {
|
|
77
|
+
return raw
|
|
72
78
|
.replace(/^<title>/i, "")
|
|
73
79
|
.replace(/<\/title>$/i, "")
|
|
74
80
|
.replace(/^["'「『]|["'」』]$/g, "")
|
|
75
81
|
.replace(/[.!?。!?]$/, "")
|
|
76
82
|
.trim();
|
|
83
|
+
}
|
|
84
|
+
export function normalizeGeneratedTitle(raw) {
|
|
85
|
+
// A tagged reply is authoritative (the combined title+summary answer puts
|
|
86
|
+
// the two tags on their own lines, so the old first-line-only read would
|
|
87
|
+
// have swallowed the summary into the title).
|
|
88
|
+
const tagged = TITLE_TAG.exec(raw)?.[1];
|
|
89
|
+
const candidate = tagged ?? raw.trim().split(/\r?\n/, 1)[0] ?? "";
|
|
90
|
+
const title = stripTitleDecoration(candidate.trim());
|
|
77
91
|
if (!title || NO_TITLE_SENTINELS.has(title.toLowerCase()))
|
|
78
92
|
return null;
|
|
79
93
|
// Reject overlong output (model answered instead of titling)
|
|
@@ -83,6 +97,24 @@ export function normalizeGeneratedTitle(raw) {
|
|
|
83
97
|
return null;
|
|
84
98
|
return title;
|
|
85
99
|
}
|
|
100
|
+
/** The one-sentence session summary that rides the title call. Null when the
|
|
101
|
+
* model answered with a bare title (older prompts, weak models) — the resume
|
|
102
|
+
* list then falls back to the title/preview it showed before. */
|
|
103
|
+
export function normalizeGeneratedSummary(raw) {
|
|
104
|
+
const tagged = SUMMARY_TAG.exec(raw)?.[1];
|
|
105
|
+
if (tagged === undefined)
|
|
106
|
+
return null;
|
|
107
|
+
const summary = tagged.replace(/\s+/g, " ").trim();
|
|
108
|
+
if (!summary || NO_TITLE_SENTINELS.has(summary.toLowerCase()))
|
|
109
|
+
return null;
|
|
110
|
+
if (summary.length <= MAX_SUMMARY_CHARS)
|
|
111
|
+
return summary;
|
|
112
|
+
// Long answers are model overshoot: keep the first sentence-ish slice at a
|
|
113
|
+
// word boundary rather than a hard cut mid-word.
|
|
114
|
+
const clipped = summary.slice(0, MAX_SUMMARY_CHARS);
|
|
115
|
+
const lastSpace = clipped.lastIndexOf(" ");
|
|
116
|
+
return `${(lastSpace > MAX_SUMMARY_CHARS / 2 ? clipped.slice(0, lastSpace) : clipped).trimEnd()}…`;
|
|
117
|
+
}
|
|
86
118
|
// ── Context builder ───────────────────────────────────────────────────────
|
|
87
119
|
export function buildTitleContext(msgs, maxTurns = 4) {
|
|
88
120
|
return msgs
|
|
@@ -92,23 +124,25 @@ export function buildTitleContext(msgs, maxTurns = 4) {
|
|
|
92
124
|
.filter((line) => line.length > 3)
|
|
93
125
|
.join("\n");
|
|
94
126
|
}
|
|
95
|
-
|
|
96
|
-
export async function generateTitle(rt, context) {
|
|
127
|
+
export async function generateTitleAndSummary(rt, context) {
|
|
97
128
|
if (!context || context.length < 4)
|
|
98
|
-
return null;
|
|
129
|
+
return { title: null, summary: null };
|
|
99
130
|
if (isLowSignalTitleInput(context))
|
|
100
|
-
return null;
|
|
131
|
+
return { title: null, summary: null };
|
|
101
132
|
try {
|
|
102
133
|
const ephemeral = rt.runEphemeralTurn;
|
|
103
134
|
if (!ephemeral)
|
|
104
|
-
return null;
|
|
135
|
+
return { title: null, summary: null };
|
|
105
136
|
const raw = await ephemeral(`${TITLE_SYSTEM_PROMPT}\n\n<conversation>\n${context}\n</conversation>`, { signal: rt.signal });
|
|
106
|
-
return
|
|
137
|
+
return {
|
|
138
|
+
title: normalizeGeneratedTitle(raw),
|
|
139
|
+
summary: normalizeGeneratedSummary(raw),
|
|
140
|
+
};
|
|
107
141
|
}
|
|
108
142
|
catch (err) {
|
|
109
143
|
// Silent-null used to hide provider failures entirely — surface them so
|
|
110
144
|
// "auto title stopped working" is diagnosable from the child's stderr.
|
|
111
145
|
console.warn(`[oma] auto-title generation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
112
|
-
return null;
|
|
146
|
+
return { title: null, summary: null };
|
|
113
147
|
}
|
|
114
148
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-pruning.d.ts","sourceRoot":"","sources":["../../../src/core/runtime/tool-pruning.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"tool-pruning.d.ts","sourceRoot":"","sources":["../../../src/core/runtime/tool-pruning.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGrD,iDAAiD;AACjD,MAAM,WAAW,WAAW;IAC1B;0EACsE;IACtE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;8CAC0C;IAC1C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;4BAEwB;IACxB,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC9C;AA6BD;;;;;;;;;mFASmF;AACnF,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAChC;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAiE9C"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { estimateMessageTokens } from "./context-estimate.js";
|
|
1
2
|
const DEFAULT_CONFIG = {
|
|
2
3
|
protectTokens: 8_000,
|
|
3
4
|
minimumSavings: 500,
|
|
@@ -12,22 +13,13 @@ function isAlreadyPruned(message) {
|
|
|
12
13
|
typeof b.content === "string" &&
|
|
13
14
|
b.content.startsWith(PRUNED_PREFIX));
|
|
14
15
|
}
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (b.type === "tool_result" && typeof b.content === "string")
|
|
23
|
-
chars += b.content.length;
|
|
24
|
-
else if (b.type === "text")
|
|
25
|
-
chars += b.text.length;
|
|
26
|
-
}
|
|
27
|
-
return Math.ceil(chars / 4);
|
|
28
|
-
}
|
|
29
|
-
return Math.ceil((message.text?.length ?? 0) / 4);
|
|
30
|
-
}
|
|
16
|
+
/** Same estimator the compaction budget uses (context-estimate.ts), so the
|
|
17
|
+
* pruning window and "savedTokens" are on the budget's scale. A local copy
|
|
18
|
+
* that counted different block types made those numbers incomparable.
|
|
19
|
+
*
|
|
20
|
+
* Note: the loop still decides compaction on the STORED entries, so a pruned
|
|
21
|
+
* result does not by itself lower the threshold estimate. */
|
|
22
|
+
const estimateTokens = estimateMessageTokens;
|
|
31
23
|
/** Prune old tool-result content from a message list.
|
|
32
24
|
*
|
|
33
25
|
* Walks backward from the newest message, accumulating tool-result tokens.
|
|
@@ -19,19 +19,49 @@ export declare function sessionDirFor(workspaceRoot: string): string;
|
|
|
19
19
|
* workspaces never see each other's sessions. OMA_SESSION_DIR overrides
|
|
20
20
|
* the WHOLE store as a flat directory (pi's PI_CODING_AGENT_SESSION_DIR). */
|
|
21
21
|
export declare function sessionDir(): string;
|
|
22
|
+
/** Session ids reach the FILESYSTEM, and callers supply them (RPC resume,
|
|
23
|
+
* TUI rename/delete): validate at this boundary. A path-shaped id
|
|
24
|
+
* ("../x", "/abs", "a\\b", "..", trailing dots) would otherwise escape the
|
|
25
|
+
* session directory and read/append/rename/delete outside it. Legit ids
|
|
26
|
+
* are newSessionId() UUIDs (hex + dashes). */
|
|
27
|
+
export declare function assertSafeSessionId(id: string): string;
|
|
22
28
|
export declare function sessionPath(id: string): string;
|
|
23
29
|
export declare function newSessionId(): string;
|
|
24
30
|
/** Load the transcript messages of a session file (wire-loose shape).
|
|
25
|
-
* Missing/corrupt files yield [] (the caller falls back to a fresh
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
31
|
+
* Missing/corrupt files yield [] (the caller falls back to a fresh session).
|
|
32
|
+
*
|
|
33
|
+
* A compaction event carries `replacesEarlierMessages`: whether its summary
|
|
34
|
+
* describes everything written before it. Only then is folding lossless —
|
|
35
|
+
* the summary becomes one context message and later turns stay live.
|
|
36
|
+
*
|
|
37
|
+
* Why a flag and not a count: the count would have to be expressed in THIS
|
|
38
|
+
* file's message-event space, but the run that produces the summary counts
|
|
39
|
+
* coverage over its own session branch, and the two spaces do not align —
|
|
40
|
+
* the branch also holds entries that never reach the file (re-seeded
|
|
41
|
+
* `product_history`, the `meta` entry) and folds a prior summary into a
|
|
42
|
+
* single entry. A count in the wrong space lands past the real boundary and
|
|
43
|
+
* DELETES messages the summary never described. The flag cannot be
|
|
44
|
+
* mis-indexed: when the summary does not describe the whole file, the
|
|
45
|
+
* transcript is simply left intact (a resume may re-summarize, never lose).
|
|
46
|
+
*
|
|
47
|
+
* Events without the field (files written before it existed) keep the
|
|
48
|
+
* historical behavior: the summary replaces everything before it.
|
|
49
|
+
*
|
|
50
|
+
* The LAST event that says "replaces" decides the fold, and a later event
|
|
51
|
+
* saying otherwise does NOT cancel it. That distinction is what makes manual
|
|
52
|
+
* /compact stick: /compact folds the transcript to one summary, a later
|
|
53
|
+
* automatic compaction covers only part of what follows, and "latest event
|
|
54
|
+
* wins" would resurrect every message the user deliberately compacted away.
|
|
55
|
+
* Ignoring a partial summary is always safe — its content is either already
|
|
56
|
+
* summarized or still present as messages. */
|
|
29
57
|
export declare function loadSessionMessages(id: string, dir?: string): Record<string, unknown>[];
|
|
30
58
|
export interface SessionSummary {
|
|
31
59
|
readonly id: string;
|
|
32
60
|
readonly modifiedAt: number;
|
|
33
61
|
/** Auto title from the last completed run's title event, when present. */
|
|
34
62
|
readonly title?: string;
|
|
63
|
+
/** One-sentence content summary (the `summary` event), when present. */
|
|
64
|
+
readonly summary?: string;
|
|
35
65
|
/** First user message text (truncated), fallback when no title exists. */
|
|
36
66
|
readonly preview: string;
|
|
37
67
|
/** Workspace root the session was created in (from the file header's
|
|
@@ -56,15 +86,71 @@ export declare function readSessionTitle(id: string, dir?: string): string | und
|
|
|
56
86
|
* loop after each completed run. Last one wins in listings. Also the
|
|
57
87
|
* primitive for /rename: appending a new title overrides the display. */
|
|
58
88
|
export declare function appendSessionTitle(id: string, title: string, dir?: string): void;
|
|
89
|
+
/** Append a summary event: a one-sentence description of what the session is
|
|
90
|
+
* about, produced by the same ephemeral call as the title. Last one wins in
|
|
91
|
+
* listings (the resume list shows it next to the title). */
|
|
92
|
+
export declare function appendSessionSummary(id: string, summary: string, dir?: string): void;
|
|
59
93
|
/** Delete a session file. Returns false when it did not exist. */
|
|
60
94
|
export declare function deleteSession(id: string, dir?: string): boolean;
|
|
61
95
|
/** Rename a session's display title (last-wins title event). Returns false
|
|
62
96
|
* when the session file does not exist. */
|
|
63
97
|
export declare function renameSession(id: string, title: string, dir?: string): boolean;
|
|
98
|
+
/** Append a goal-mode event (omp mode-change analogue): the latest goal
|
|
99
|
+
* state transition for the session. Replay reconstructs the current goal
|
|
100
|
+
* (active/paused/complete/dropped); a goal:null event means dropped. */
|
|
101
|
+
export declare function appendSessionGoalEvent(id: string, state: {
|
|
102
|
+
enabled: boolean;
|
|
103
|
+
mode: "active" | "exiting";
|
|
104
|
+
reason?: "completed";
|
|
105
|
+
goal: unknown;
|
|
106
|
+
} | null, dir?: string): void;
|
|
107
|
+
/** Append a goal COMPLETION record: the objective and the tracked usage at the
|
|
108
|
+
* moment the model declared the goal done. Separate from the mode-change
|
|
109
|
+
* events so a completed goal reads as a durable achievement rather than a
|
|
110
|
+
* status flip (and so resumed sessions can report what was finished). */
|
|
111
|
+
export declare function appendSessionGoalCompletion(id: string, record: {
|
|
112
|
+
objective: string;
|
|
113
|
+
tokensUsed: number;
|
|
114
|
+
tokenBudget?: number;
|
|
115
|
+
timeUsedSeconds: number;
|
|
116
|
+
}, dir?: string): void;
|
|
117
|
+
/** Append a plan-mode event (same mode-change shape as the goal one): the
|
|
118
|
+
* mode plus whether it is paused. The draft itself is a FILE, so the journal
|
|
119
|
+
* only needs the mode; resume restores "planning, paused" and never
|
|
120
|
+
* re-enters a read-only planning turn on its own. */
|
|
121
|
+
export declare function appendSessionPlanEvent(id: string, state: {
|
|
122
|
+
planPath: string;
|
|
123
|
+
} | null, paused: boolean, dir?: string): void;
|
|
124
|
+
/** Replay plan-mode events: the latest one wins (null = plan mode off). */
|
|
125
|
+
export declare function loadSessionPlanState(id: string, dir?: string): {
|
|
126
|
+
planPath: string;
|
|
127
|
+
paused: boolean;
|
|
128
|
+
} | null;
|
|
129
|
+
/** Reconstruct the current goal-mode state by replaying goal events (last
|
|
130
|
+
* one wins; malformed entries are skipped like every other scan here). */
|
|
131
|
+
export declare function loadSessionGoalState(id: string, dir?: string): {
|
|
132
|
+
enabled: boolean;
|
|
133
|
+
mode: "active" | "exiting";
|
|
134
|
+
reason?: "completed";
|
|
135
|
+
goal: {
|
|
136
|
+
id: string;
|
|
137
|
+
objective: string;
|
|
138
|
+
status: "active" | "paused" | "budget-limited" | "complete" | "dropped";
|
|
139
|
+
tokenBudget?: number;
|
|
140
|
+
tokensUsed: number;
|
|
141
|
+
timeUsedSeconds: number;
|
|
142
|
+
createdAt: number;
|
|
143
|
+
updatedAt: number;
|
|
144
|
+
};
|
|
145
|
+
} | null;
|
|
64
146
|
/** Append a compaction event: records that the run compacted everything
|
|
65
147
|
* recorded so far in this file into `summary`. Must be called AFTER the
|
|
66
148
|
* turn's messages are appended. */
|
|
67
|
-
export declare function appendSessionCompaction(id: string, summary: string, dir?: string
|
|
149
|
+
export declare function appendSessionCompaction(id: string, summary: string, dir?: string,
|
|
150
|
+
/** Whether this summary describes EVERYTHING already in the file, which is
|
|
151
|
+
* what makes folding on load lossless. Omit when unknown: the load path
|
|
152
|
+
* then keeps the transcript intact instead of folding it. */
|
|
153
|
+
replacesEarlierMessages?: boolean): void;
|
|
68
154
|
export interface SessionBranchNode {
|
|
69
155
|
readonly id: string;
|
|
70
156
|
readonly parentId: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-file.d.ts","sourceRoot":"","sources":["../../../src/core/session/session-file.ts"],"names":[],"mappings":"AAaA;;;;;;;4EAO4E;AAE5E;;6CAE6C;AAC7C,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED,0CAA0C;AAC1C,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED;;;8EAG8E;AAC9E,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED
|
|
1
|
+
{"version":3,"file":"session-file.d.ts","sourceRoot":"","sources":["../../../src/core/session/session-file.ts"],"names":[],"mappings":"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"}
|