@kkelly-offical/kkcode 0.1.6 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/LICENSE +674 -674
  2. package/README.md +452 -387
  3. package/package.json +50 -46
  4. package/src/agent/agent.mjs +19 -2
  5. package/src/agent/custom-agent-loader.mjs +6 -3
  6. package/src/agent/generator.mjs +2 -2
  7. package/src/agent/prompt/assistant.txt +12 -0
  8. package/src/agent/prompt/bug-hunter.txt +90 -0
  9. package/src/agent/prompt/frontend-designer.txt +58 -58
  10. package/src/agent/prompt/guide.txt +1 -1
  11. package/src/agent/prompt/longagent-blueprint-agent.txt +83 -83
  12. package/src/agent/prompt/longagent-coding-agent.txt +37 -37
  13. package/src/agent/prompt/longagent-debugging-agent.txt +46 -46
  14. package/src/agent/prompt/longagent-preview-agent.txt +63 -63
  15. package/src/command/custom-commands.mjs +2 -2
  16. package/src/commands/agent.mjs +1 -1
  17. package/src/commands/background.mjs +145 -4
  18. package/src/commands/chat.mjs +117 -76
  19. package/src/commands/config.mjs +148 -1
  20. package/src/commands/doctor.mjs +30 -6
  21. package/src/commands/init.mjs +32 -6
  22. package/src/commands/longagent.mjs +117 -0
  23. package/src/commands/mcp.mjs +275 -43
  24. package/src/commands/permission.mjs +1 -1
  25. package/src/commands/session.mjs +195 -140
  26. package/src/commands/skill.mjs +63 -0
  27. package/src/commands/theme.mjs +1 -1
  28. package/src/config/defaults.mjs +280 -260
  29. package/src/config/import-config.mjs +1 -1
  30. package/src/config/load-config.mjs +61 -4
  31. package/src/config/schema.mjs +591 -574
  32. package/src/context.mjs +4 -1
  33. package/src/core/constants.mjs +97 -91
  34. package/src/core/types.mjs +1 -1
  35. package/src/github/api.mjs +78 -78
  36. package/src/github/auth.mjs +294 -286
  37. package/src/github/flow.mjs +298 -298
  38. package/src/github/workspace.mjs +225 -212
  39. package/src/index.mjs +84 -82
  40. package/src/knowledge/frontend-aesthetics.txt +38 -38
  41. package/src/mcp/client-http.mjs +139 -141
  42. package/src/mcp/client-sse.mjs +297 -288
  43. package/src/mcp/client-stdio.mjs +534 -533
  44. package/src/mcp/constants.mjs +2 -2
  45. package/src/mcp/registry.mjs +498 -479
  46. package/src/mcp/stdio-framing.mjs +135 -133
  47. package/src/mcp/tool-result.mjs +24 -24
  48. package/src/observability/edit-diagnostics.mjs +449 -0
  49. package/src/observability/index.mjs +42 -42
  50. package/src/observability/metrics.mjs +165 -137
  51. package/src/observability/tracer.mjs +137 -137
  52. package/src/onboarding.mjs +209 -0
  53. package/src/orchestration/background-manager.mjs +567 -372
  54. package/src/orchestration/background-worker.mjs +419 -305
  55. package/src/orchestration/interruption-reason.mjs +21 -0
  56. package/src/orchestration/longagent-manager.mjs +197 -171
  57. package/src/orchestration/stage-scheduler.mjs +733 -728
  58. package/src/orchestration/subagent-router.mjs +7 -1
  59. package/src/orchestration/task-scheduler.mjs +219 -7
  60. package/src/permission/engine.mjs +1 -1
  61. package/src/permission/exec-policy.mjs +370 -370
  62. package/src/permission/file-edit-policy.mjs +108 -0
  63. package/src/permission/prompt.mjs +1 -1
  64. package/src/permission/rules.mjs +116 -7
  65. package/src/plugin/builtin-hooks/post-edit-format.mjs +2 -1
  66. package/src/plugin/builtin-hooks/post-edit-typecheck.mjs +104 -40
  67. package/src/plugin/hook-bus.mjs +19 -5
  68. package/src/plugin/manifest-loader.mjs +222 -0
  69. package/src/provider/anthropic.mjs +396 -390
  70. package/src/provider/ollama.mjs +7 -1
  71. package/src/provider/openai.mjs +382 -340
  72. package/src/provider/retry-policy.mjs +74 -68
  73. package/src/provider/router.mjs +242 -241
  74. package/src/provider/sse.mjs +104 -104
  75. package/src/provider/wizard.mjs +556 -0
  76. package/src/repl/capability-facade.mjs +30 -0
  77. package/src/repl/command-surface.mjs +23 -0
  78. package/src/repl/controller-entry.mjs +40 -0
  79. package/src/repl/core-shell.mjs +208 -0
  80. package/src/repl/dialog-router.mjs +87 -0
  81. package/src/repl/input-engine.mjs +76 -0
  82. package/src/repl/keymap.mjs +7 -0
  83. package/src/repl/operator-surface.mjs +15 -0
  84. package/src/repl/permission-flow.mjs +49 -0
  85. package/src/repl/runtime-facade.mjs +36 -0
  86. package/src/repl/slash-router.mjs +62 -0
  87. package/src/repl/state-store.mjs +29 -0
  88. package/src/repl/turn-controller.mjs +58 -0
  89. package/src/repl/verification.mjs +23 -0
  90. package/src/repl.mjs +3368 -2929
  91. package/src/rules/load-rules.mjs +3 -3
  92. package/src/runtime.mjs +1 -1
  93. package/src/session/agent-transaction.mjs +86 -0
  94. package/src/session/checkpoint.mjs +302 -302
  95. package/src/session/compaction.mjs +36 -14
  96. package/src/session/engine.mjs +417 -227
  97. package/src/session/longagent-4stage.mjs +467 -460
  98. package/src/session/longagent-hybrid.mjs +1344 -1081
  99. package/src/session/longagent-plan.mjs +376 -365
  100. package/src/session/longagent-project-memory.mjs +53 -53
  101. package/src/session/longagent-scaffold.mjs +291 -291
  102. package/src/session/longagent-task-bus.mjs +138 -54
  103. package/src/session/longagent-utils.mjs +828 -472
  104. package/src/session/longagent.mjs +911 -884
  105. package/src/session/loop.mjs +1005 -905
  106. package/src/session/prompt/agent.txt +25 -0
  107. package/src/session/prompt/anthropic.txt +150 -150
  108. package/src/session/prompt/beast.txt +1 -1
  109. package/src/session/prompt/plan.txt +28 -6
  110. package/src/session/prompt/qwen.txt +46 -46
  111. package/src/session/recovery.mjs +21 -0
  112. package/src/session/rollback.mjs +197 -0
  113. package/src/session/routing-observability.mjs +72 -0
  114. package/src/session/runtime-state.mjs +47 -0
  115. package/src/session/store.mjs +523 -510
  116. package/src/session/system-prompt.mjs +56 -8
  117. package/src/session/task-validator.mjs +267 -267
  118. package/src/session/usability-gates.mjs +2 -2
  119. package/src/skill/builtin/commit.mjs +64 -64
  120. package/src/skill/builtin/design.mjs +76 -76
  121. package/src/skill/generator.mjs +18 -2
  122. package/src/skill/registry.mjs +642 -390
  123. package/src/storage/audit-store.mjs +18 -11
  124. package/src/storage/event-log.mjs +7 -1
  125. package/src/storage/ghost-commit-store.mjs +243 -245
  126. package/src/storage/paths.mjs +13 -0
  127. package/src/theme/default-theme.mjs +1 -1
  128. package/src/theme/markdown.mjs +4 -0
  129. package/src/theme/schema.mjs +1 -1
  130. package/src/theme/status-bar.mjs +162 -158
  131. package/src/tool/audit-wrapper.mjs +18 -2
  132. package/src/tool/edit-transaction.mjs +23 -0
  133. package/src/tool/executor.mjs +26 -1
  134. package/src/tool/file-read-state.mjs +65 -0
  135. package/src/tool/git-auto.mjs +526 -526
  136. package/src/tool/git-full-auto.mjs +487 -478
  137. package/src/tool/mutation-guard.mjs +54 -0
  138. package/src/tool/prompt/edit.txt +3 -3
  139. package/src/tool/prompt/multiedit.txt +1 -0
  140. package/src/tool/prompt/notebookedit.txt +2 -1
  141. package/src/tool/prompt/patch.txt +25 -24
  142. package/src/tool/prompt/read.txt +3 -3
  143. package/src/tool/prompt/sysinfo.txt +29 -0
  144. package/src/tool/prompt/task.txt +66 -4
  145. package/src/tool/prompt/write.txt +2 -2
  146. package/src/tool/question-prompt.mjs +17 -4
  147. package/src/tool/registry.mjs +1701 -1343
  148. package/src/tool/task-tool.mjs +14 -6
  149. package/src/ui/activity-renderer.mjs +667 -664
  150. package/src/ui/repl-background-panel.mjs +7 -0
  151. package/src/ui/repl-capability-panel.mjs +9 -0
  152. package/src/ui/repl-dashboard.mjs +54 -4
  153. package/src/ui/repl-help.mjs +110 -0
  154. package/src/ui/repl-operator-panel.mjs +12 -0
  155. package/src/ui/repl-route-feedback.mjs +35 -0
  156. package/src/ui/repl-status-view.mjs +76 -0
  157. package/src/ui/repl-task-panel.mjs +5 -0
  158. package/src/ui/repl-transcript-panel.mjs +56 -0
  159. package/src/ui/repl-turn-summary.mjs +135 -0
  160. package/src/usage/pricing.mjs +122 -121
  161. package/src/usage/usage-meter.mjs +1 -0
  162. package/src/util/git.mjs +562 -519
  163. package/src/util/template.mjs +6 -1
@@ -40,6 +40,7 @@ Rules:
40
40
  const DEFAULT_THRESHOLD_MESSAGES = 50
41
41
  const DEFAULT_THRESHOLD_RATIO = 0.7
42
42
  const DEFAULT_KEEP_RECENT = 6
43
+ const DEFAULT_KEEP_RECENT_TURNS = 3
43
44
  const TOOL_RESULT_PREVIEW_LIMIT = 200
44
45
 
45
46
  // Estimate tokens from a string, accounting for CJK characters (~1.5 chars/token vs ~4 for Latin)
@@ -84,21 +85,32 @@ export function estimateTokenCount(messages) {
84
85
 
85
86
  /**
86
87
  * Pre-prune messages before LLM summarization.
87
- * - Truncate large tool_result content to a short preview
88
+ * - Strip synthetic scaffolding messages (continuation noise)
89
+ * - Truncate large tool_result content with aging: older steps get shorter previews
88
90
  * - Keep tool_use blocks intact (they show model intent)
89
91
  * - Truncate very long plain-text assistant/user messages
90
92
  */
91
93
  export function pruneForSummary(messages, previewLimit = TOOL_RESULT_PREVIEW_LIMIT) {
92
- return messages.map((msg) => {
94
+ // Strip synthetic scaffolding messages (continuation prompts, fake tool_result errors)
95
+ const real = messages.filter(msg => !msg.synthetic)
96
+
97
+ // #2 工具结果老化: find max step to compute relative age per message
98
+ const maxStep = real.reduce((m, msg) => Math.max(m, msg.step || 0), 0)
99
+
100
+ return real.map((msg) => {
101
+ // Aging: older tool_results get more aggressive truncation
102
+ const age = maxStep - (msg.step || 0)
103
+ const effectiveLimit = Math.max(50, previewLimit - age * 15)
104
+
93
105
  const content = msg.content
94
106
  if (Array.isArray(content)) {
95
107
  const pruned = content.map((block) => {
96
108
  if (block.type === "tool_result") {
97
109
  const raw = String(block.content || "")
98
- if (raw.length > previewLimit) {
110
+ if (raw.length > effectiveLimit) {
99
111
  return {
100
112
  ...block,
101
- content: `${raw.slice(0, previewLimit)}... [truncated ${raw.length} chars]`
113
+ content: `${raw.slice(0, effectiveLimit)}... [truncated ${raw.length} chars, age=${age}]`
102
114
  }
103
115
  }
104
116
  }
@@ -177,22 +189,32 @@ export async function compactSession({
177
189
  providerType,
178
190
  configState,
179
191
  keepRecent = DEFAULT_KEEP_RECENT,
192
+ keepRecentTurns = DEFAULT_KEEP_RECENT_TURNS,
180
193
  baseUrl = null,
181
194
  apiKeyEnv = null
182
195
  }) {
183
196
  const history = await getConversationHistory(sessionId, 9999)
184
197
  if (history.length <= keepRecent + 2) return { compacted: false, reason: "too few messages" }
185
198
 
186
- // Find split point that doesn't break tool_use/tool_result pairs
187
- let splitIdx = history.length - keepRecent
188
- while (splitIdx > 0 && splitIdx < history.length) {
189
- const msg = history[splitIdx]
190
- const content = msg.content
191
- if (Array.isArray(content) && content.some(b => b.type === "tool_result")) {
192
- splitIdx-- // include the paired assistant tool_use message
193
- continue
199
+ // Turn-based split: keep last keepRecentTurns complete turns
200
+ // A "turn" = one user interaction cycle (user msg + model response + all tool calls)
201
+ // Falls back to message-count if no turnId metadata is present
202
+ let splitIdx
203
+ const turnIds = []
204
+ const seenTurns = new Set()
205
+ for (const msg of history) {
206
+ if (msg.turnId && !seenTurns.has(msg.turnId)) {
207
+ seenTurns.add(msg.turnId)
208
+ turnIds.push(msg.turnId)
194
209
  }
195
- break
210
+ }
211
+ if (turnIds.length > keepRecentTurns) {
212
+ const keepFromTurnId = turnIds[turnIds.length - keepRecentTurns]
213
+ splitIdx = history.findIndex(msg => msg.turnId === keepFromTurnId)
214
+ if (splitIdx < 0) splitIdx = history.length - keepRecent
215
+ } else {
216
+ // Fallback: not enough turns, use message count
217
+ splitIdx = history.length - keepRecent
196
218
  }
197
219
  const toSummarize = history.slice(0, splitIdx)
198
220
  const kept = history.slice(splitIdx)
@@ -259,7 +281,7 @@ export async function compactSession({
259
281
 
260
282
  await saveCheckpoint(sessionId, {
261
283
  kind: "compaction",
262
- iteration: 0,
284
+ iteration: Date.now(),
263
285
  compactedAt: Date.now(),
264
286
  summarizeCount: toSummarize.length,
265
287
  keepCount: kept.length,