@kenkaiiii/ggcoder 5.26.2 → 5.26.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-sidecar.js +54 -47
- package/dist/app-sidecar.js.map +1 -1
- package/dist/core/agent-session-marker-anchors.test.js +181 -2
- package/dist/core/agent-session-marker-anchors.test.js.map +1 -1
- package/dist/core/agent-session-slash-restore.test.d.ts +2 -0
- package/dist/core/agent-session-slash-restore.test.d.ts.map +1 -0
- package/dist/core/agent-session-slash-restore.test.js +121 -0
- package/dist/core/agent-session-slash-restore.test.js.map +1 -0
- package/dist/core/agent-session.d.ts +26 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +92 -29
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compactor.d.ts +21 -0
- package/dist/core/compaction/compactor.d.ts.map +1 -1
- package/dist/core/compaction/compactor.js +16 -0
- package/dist/core/compaction/compactor.js.map +1 -1
- package/dist/core/compaction/compactor.test.js +91 -0
- package/dist/core/compaction/compactor.test.js.map +1 -1
- package/dist/core/session-history.d.ts +61 -4
- package/dist/core/session-history.d.ts.map +1 -1
- package/dist/core/session-history.js +144 -15
- package/dist/core/session-history.js.map +1 -1
- package/dist/core/session-history.test.js +50 -1
- package/dist/core/session-history.test.js.map +1 -1
- package/dist/core/session-manager.d.ts +30 -5
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +37 -9
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-manager.test.js +14 -2
- package/dist/core/session-manager.test.js.map +1 -1
- package/package.json +4 -4
package/dist/app-sidecar.js
CHANGED
|
@@ -34,7 +34,7 @@ import { parseAutopilotVerdict } from "./core/autopilot-verdict.js";
|
|
|
34
34
|
import { isWorkflowCommandText, countAssistantMessages, shouldStartAutopilotCycle, extractTurnToolCalls, isMechanicalOnlyTurn, } from "./core/autopilot-gate.js";
|
|
35
35
|
import { driveAutopilotCycle, frameAutopilotInjection } from "./core/autopilot-cycle.js";
|
|
36
36
|
import { validateKenModelPref, effectiveKenModel } from "./core/ken-model.js";
|
|
37
|
-
import { normalizeAutopilotMarkersForHistory, normalizeAppMarkersForHistory, normalizeKenTurnsForHistory, restoreUserRow, restoreAssistantTexts, autopilotMarkerCopySeed, } from "./core/session-history.js";
|
|
37
|
+
import { normalizeAutopilotMarkersForHistory, normalizeAppMarkersForHistory, normalizeKenTurnsForHistory, restoreUserRow, restoreAssistantTexts, resolveRestoredCommand, autopilotMarkerCopySeed, } from "./core/session-history.js";
|
|
38
38
|
import { sessionToMarkdown, defaultExportFilename, } from "./core/session-export.js";
|
|
39
39
|
import { AuthStorage } from "./core/auth-storage.js";
|
|
40
40
|
import { cleanupToolOutputs } from "./tools/overflow.js";
|
|
@@ -364,30 +364,6 @@ function detectHookKind(text) {
|
|
|
364
364
|
return "regrounding";
|
|
365
365
|
return null;
|
|
366
366
|
}
|
|
367
|
-
// Separator AgentSession.prompt() inserts between a command's prompt body and
|
|
368
|
-
// the user's trailing args. Must stay in sync with the expansion there.
|
|
369
|
-
const COMMAND_ARGS_SEP = "\n\n## User Instructions\n\n";
|
|
370
|
-
/**
|
|
371
|
-
* Reverse a prompt-template command's expansion. When a `/name` command runs,
|
|
372
|
-
* the agent persists the FULL expanded prompt body as the user message — so on
|
|
373
|
-
* resume the raw body would render instead of the short `/name` chip the user
|
|
374
|
-
* saw live. Given the candidate commands (built-in + custom) and a restored
|
|
375
|
-
* message body, recover the original `/name [args]` invocation. Returns null
|
|
376
|
-
* when the text isn't a known command body (an ordinary user message).
|
|
377
|
-
*/
|
|
378
|
-
function detectPromptCommand(text, candidates) {
|
|
379
|
-
for (const c of candidates) {
|
|
380
|
-
if (!c.prompt)
|
|
381
|
-
continue;
|
|
382
|
-
if (text === c.prompt)
|
|
383
|
-
return `/${c.name}`;
|
|
384
|
-
if (text.startsWith(c.prompt + COMMAND_ARGS_SEP)) {
|
|
385
|
-
const args = text.slice(c.prompt.length + COMMAND_ARGS_SEP.length).trim();
|
|
386
|
-
return args ? `/${c.name} ${args}` : `/${c.name}`;
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
return null;
|
|
390
|
-
}
|
|
391
367
|
/** A short transport summary for display (URL for http/sse, command+args for stdio). */
|
|
392
368
|
function mcpRowSummary(config) {
|
|
393
369
|
if (config.url)
|
|
@@ -2121,12 +2097,14 @@ async function createSession(deps, opts) {
|
|
|
2121
2097
|
// falling back to the raw verdict text (e.g. ALL_CLEAR).
|
|
2122
2098
|
if (event.type === "autopilot_done") {
|
|
2123
2099
|
// Broadcast the SAME copySeed the persisted marker will produce on
|
|
2124
|
-
// resume, so the live all-clear wording matches the resumed one
|
|
2125
|
-
//
|
|
2100
|
+
// resume, so the live all-clear wording matches the resumed one.
|
|
2101
|
+
// Must use the PERSISTED count — that's what persistAutopilotMarker
|
|
2102
|
+
// anchors against, and it trails the in-memory list after a run
|
|
2103
|
+
// whose messages never made it to disk.
|
|
2126
2104
|
const seed = autopilotMarkerCopySeed({
|
|
2127
2105
|
version: 1,
|
|
2128
2106
|
phase: "done",
|
|
2129
|
-
afterMessageCount: session.
|
|
2107
|
+
afterMessageCount: session.getPersistedTranscriptCount(),
|
|
2130
2108
|
});
|
|
2131
2109
|
broadcast(event.type, { ...event.data, copySeed: seed });
|
|
2132
2110
|
void session.persistAutopilotMarker("done");
|
|
@@ -2698,9 +2676,9 @@ async function createSession(deps, opts) {
|
|
|
2698
2676
|
// Autopilot verdict markers to interleave, same anchor scheme as Ken
|
|
2699
2677
|
// turns — each becomes a single assistant row the webview renders
|
|
2700
2678
|
// exactly like the live `autopilot` item (never a raw verdict string).
|
|
2701
|
-
//
|
|
2702
|
-
//
|
|
2703
|
-
//
|
|
2679
|
+
// Normalization pulls anchors left over from an unrebased compaction
|
|
2680
|
+
// back to where the marker was actually written, so stale all-clear
|
|
2681
|
+
// bubbles no longer bunch at the bottom of a reopened session.
|
|
2704
2682
|
const restoredMessageCount = messages.filter((m) => m.role !== "system").length;
|
|
2705
2683
|
const autopilotByCount = new Map();
|
|
2706
2684
|
for (const marker of normalizeAutopilotMarkersForHistory(session.getAutopilotMarkers(), restoredMessageCount)) {
|
|
@@ -2850,9 +2828,21 @@ async function createSession(deps, opts) {
|
|
|
2850
2828
|
const text = restored.text;
|
|
2851
2829
|
const hook = detectHookKind(text);
|
|
2852
2830
|
const compacted = !hook && text.startsWith("[Previous conversation summary]");
|
|
2853
|
-
const
|
|
2854
|
-
|
|
2855
|
-
|
|
2831
|
+
const hint = userHintByCount.get(nonSystemCount);
|
|
2832
|
+
// The typed invocation persisted alongside the prompt is
|
|
2833
|
+
// authoritative. Reversing the expanded body only works while the
|
|
2834
|
+
// template is byte-identical, and templates drift (edited
|
|
2835
|
+
// `.gg/commands/*.md`, reworded built-ins, app-vs-CLI phrasing) —
|
|
2836
|
+
// after which the resumed session dumped the raw multi-KB body
|
|
2837
|
+
// instead of the `/name` chip. Older sessions have no hint, so the
|
|
2838
|
+
// body match stays as the fallback.
|
|
2839
|
+
const command = !hook && !compacted
|
|
2840
|
+
? resolveRestoredCommand(typeof hint?.command === "string" ? hint.command : null, text, commandCandidates)
|
|
2841
|
+
: null;
|
|
2842
|
+
// Autopilot injected this turn — live showed only the Ken-tinted
|
|
2843
|
+
// marker for it, never a user bubble. Emitting one here would print
|
|
2844
|
+
// the injected instruction a second time, unstyled.
|
|
2845
|
+
if (!restored.autopilotInjected && (text.trim() || restored.images.length > 0)) {
|
|
2856
2846
|
history.push({
|
|
2857
2847
|
role: "user",
|
|
2858
2848
|
text: command ?? text,
|
|
@@ -3032,15 +3022,39 @@ async function createSession(deps, opts) {
|
|
|
3032
3022
|
// yield, and `running` does not flip until runAgent begins.
|
|
3033
3023
|
claimedStart = runClaim.claim();
|
|
3034
3024
|
json(res, 202, { accepted: true });
|
|
3025
|
+
// Gate inputs captured around the run: whether this turn is a workflow
|
|
3026
|
+
// slash command (attachment prompts skip slash expansion entirely), and
|
|
3027
|
+
// how many assistant messages the run actually adds. Computed even when
|
|
3028
|
+
// autopilot is currently off — the toggle can flip ON mid-run, and the
|
|
3029
|
+
// gate reads the post-run value.
|
|
3030
|
+
const workflowCommand = attachments.length === 0 &&
|
|
3031
|
+
isWorkflowCommandText(text, await loadWorkflowCommandSpecs());
|
|
3032
|
+
// Does this input actually expand into a persisted user message? Asked
|
|
3033
|
+
// of the session itself, because only it knows whether the command
|
|
3034
|
+
// resolves here (name/alias casing, custom `.gg/commands`, non-coder
|
|
3035
|
+
// agents that don't expand at all). A looser guess would anchor the
|
|
3036
|
+
// hint at +1 with no message to land on — decorating an unrelated
|
|
3037
|
+
// later bubble with the wrong `/name`.
|
|
3038
|
+
const expandsToTemplate = attachments.length === 0 && (await session.willExpandPromptTemplate(text));
|
|
3035
3039
|
// Webview display hint for this prompt's user bubble (kenSent shimmer
|
|
3036
|
-
// label / enhancer highlight segments
|
|
3037
|
-
// the user message the prompt below
|
|
3038
|
-
// skip this (their position in the run
|
|
3039
|
-
|
|
3040
|
+
// label / enhancer highlight segments / the `/name` a command was typed
|
|
3041
|
+
// as). Anchored +1 so it attaches to the user message the prompt below
|
|
3042
|
+
// is about to push. Queued prompts skip this (their position in the run
|
|
3043
|
+
// is unpredictable).
|
|
3044
|
+
//
|
|
3045
|
+
// Recording the invocation matters because the agent persists the
|
|
3046
|
+
// EXPANDED template as the user message. Resume used to recover
|
|
3047
|
+
// `/name` by matching that body against the current templates, which
|
|
3048
|
+
// silently fails the moment a template is edited or reworded — the
|
|
3049
|
+
// reopened session then rendered the raw multi-KB prompt instead of
|
|
3050
|
+
// the command chip.
|
|
3051
|
+
if (expandsToTemplate ||
|
|
3052
|
+
(meta && (meta.kenSent === true || Array.isArray(meta.enhancements)))) {
|
|
3040
3053
|
void session
|
|
3041
3054
|
.persistAppMarker("user_hint", {
|
|
3042
|
-
...(
|
|
3043
|
-
...(
|
|
3055
|
+
...(expandsToTemplate ? { command: text.trim() } : {}),
|
|
3056
|
+
...(meta?.kenSent === true ? { kenSent: true } : {}),
|
|
3057
|
+
...(Array.isArray(meta?.enhancements) ? { enhancements: meta.enhancements } : {}),
|
|
3044
3058
|
}, 1)
|
|
3045
3059
|
.catch(() => { });
|
|
3046
3060
|
}
|
|
@@ -3051,13 +3065,6 @@ async function createSession(deps, opts) {
|
|
|
3051
3065
|
// feedback, anything) supersedes the pending plan — the bump also
|
|
3052
3066
|
// invalidates any in-flight Ken plan review.
|
|
3053
3067
|
clearPendingPlan();
|
|
3054
|
-
// Gate inputs captured around the run: whether this turn is a workflow
|
|
3055
|
-
// slash command (attachment prompts skip slash expansion entirely), and
|
|
3056
|
-
// how many assistant messages the run actually adds. Computed even when
|
|
3057
|
-
// autopilot is currently off — the toggle can flip ON mid-run, and the
|
|
3058
|
-
// gate reads the post-run value.
|
|
3059
|
-
const workflowCommand = attachments.length === 0 &&
|
|
3060
|
-
isWorkflowCommandText(text, await loadWorkflowCommandSpecs());
|
|
3061
3068
|
const assistantsBefore = countAssistantMessages(session.getMessages());
|
|
3062
3069
|
const messagesBefore = session.getMessages().length;
|
|
3063
3070
|
await runAgent(text, async () => {
|