flavor-code 1.4.0-beta.1 → 1.4.0-beta.10

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 (169) hide show
  1. package/README.md +2 -0
  2. package/README.zh-CN.md +2 -0
  3. package/dist/agent/loop.d.ts +7 -2
  4. package/dist/{app-C5ZQUOKJ.js → app-SMIB6P23.js} +44 -11
  5. package/dist/{chunk-6MNOZ2TX.js → chunk-BYHO2CA5.js} +1925 -765
  6. package/dist/{chunk-URUVFECH.js → chunk-EXOSMO57.js} +12 -7
  7. package/dist/chunk-N5MXHJKD.js +107 -0
  8. package/dist/{chunk-2BF7CVWZ.js → chunk-RAYH6K2H.js} +2 -2
  9. package/dist/{chunk-FOTMP4ZS.js → chunk-UO4DLWU5.js} +8 -2
  10. package/dist/{chunk-ODRWR4KK.js → chunk-XMRKRPNC.js} +179 -14253
  11. package/dist/{chunk-3WCDZ6ZL.js → chunk-ZJCAQXA7.js} +2 -1
  12. package/dist/{claude-ink-LP32NSX5.js → claude-ink-6EZHF64C.js} +2 -2
  13. package/dist/cli-main.js +56 -25
  14. package/dist/cli.js +54 -10
  15. package/dist/config/schema.d.ts +8 -0
  16. package/dist/context/manager.d.ts +9 -0
  17. package/dist/desktop/main.js +2318 -1071
  18. package/dist/desktop-renderer/assets/index-RNe5Gtum.js +154 -0
  19. package/dist/desktop-renderer/assets/{interactive-terminal-C4o7MNPO.js → interactive-terminal-DestMQ2z.js} +1 -1
  20. package/dist/desktop-renderer/index.html +1 -1
  21. package/dist/git/service.d.ts +3 -3
  22. package/dist/git/tools.d.ts +1 -1
  23. package/dist/goal/classifier.d.ts +2 -0
  24. package/dist/goal/orchestrator.d.ts +23 -2
  25. package/dist/goal/planner.d.ts +2 -0
  26. package/dist/goal/store.d.ts +2 -0
  27. package/dist/goal/types.d.ts +14 -0
  28. package/dist/harness/journal.d.ts +2 -0
  29. package/dist/harness/local.d.ts +2 -0
  30. package/dist/init/project.d.ts +0 -6
  31. package/dist/jobs/registry.d.ts +7 -1
  32. package/dist/{load-V2UIYYQI.js → load-EW56Q2MM.js} +1 -1
  33. package/dist/loop/orchestrator.d.ts +20 -0
  34. package/dist/loop/types.d.ts +7 -0
  35. package/dist/loop/verifier.d.ts +2 -0
  36. package/dist/models/openai.d.ts +1 -1
  37. package/dist/models/structured.d.ts +7 -0
  38. package/dist/models/types.d.ts +1 -1
  39. package/dist/production.d.ts +17 -0
  40. package/dist/sdk/index.js +5 -5
  41. package/dist/session/tree.d.ts +2 -0
  42. package/dist/tools/lsp.d.ts +15 -10
  43. package/dist/tools/runtime.d.ts +2 -1
  44. package/dist/tools/search.d.ts +1 -0
  45. package/dist/tools/types.d.ts +1 -1
  46. package/dist/ui/session.d.ts +11 -0
  47. package/dist/ui/transcript.d.ts +9 -0
  48. package/dist/utils/abort.d.ts +20 -0
  49. package/dist/utils/execFileNoThrow.d.ts +1 -0
  50. package/dist/utils/heap.d.ts +58 -0
  51. package/dist/utils/memory-restart.d.ts +42 -3
  52. package/dist/utils/process-tree.d.ts +2 -0
  53. package/dist/utils/rotation-census.d.ts +36 -0
  54. package/package.json +3 -2
  55. package//346/212/200/346/234/257/346/226/271/346/241/210/346/212/245/345/221/212.md +7 -7
  56. package/dist/astgraph/db.mjs +0 -237
  57. package/dist/astgraph/extract.mjs +0 -239
  58. package/dist/astgraph/flavor-plugin.json +0 -25
  59. package/dist/astgraph/grammars.mjs +0 -68
  60. package/dist/astgraph/index.js +0 -301
  61. package/dist/astgraph/indexer.mjs +0 -175
  62. package/dist/astgraph/query.mjs +0 -165
  63. package/dist/astgraph/resolve.mjs +0 -93
  64. package/dist/astgraph/vendor/tree-sitter-javascript.wasm +0 -0
  65. package/dist/astgraph/vendor/tree-sitter-tsx.wasm +0 -0
  66. package/dist/astgraph/vendor/tree-sitter-typescript.wasm +0 -0
  67. package/dist/astgraph/vendor/tree-sitter.js +0 -3980
  68. package/dist/astgraph/vendor/tree-sitter.wasm +0 -0
  69. package/dist/astgraph/vendor/zod/LICENSE +0 -21
  70. package/dist/astgraph/vendor/zod/index.js +0 -4
  71. package/dist/astgraph/vendor/zod/locales/index.js +0 -1
  72. package/dist/astgraph/vendor/zod/locales/package.json +0 -7
  73. package/dist/astgraph/vendor/zod/package.json +0 -135
  74. package/dist/astgraph/vendor/zod/v4/classic/checks.js +0 -1
  75. package/dist/astgraph/vendor/zod/v4/classic/coerce.js +0 -17
  76. package/dist/astgraph/vendor/zod/v4/classic/compat.js +0 -31
  77. package/dist/astgraph/vendor/zod/v4/classic/errors.js +0 -48
  78. package/dist/astgraph/vendor/zod/v4/classic/external.js +0 -20
  79. package/dist/astgraph/vendor/zod/v4/classic/from-json-schema.js +0 -599
  80. package/dist/astgraph/vendor/zod/v4/classic/index.js +0 -4
  81. package/dist/astgraph/vendor/zod/v4/classic/iso.js +0 -30
  82. package/dist/astgraph/vendor/zod/v4/classic/package.json +0 -7
  83. package/dist/astgraph/vendor/zod/v4/classic/parse.js +0 -15
  84. package/dist/astgraph/vendor/zod/v4/classic/schemas.js +0 -1395
  85. package/dist/astgraph/vendor/zod/v4/core/api.js +0 -1087
  86. package/dist/astgraph/vendor/zod/v4/core/checks.js +0 -575
  87. package/dist/astgraph/vendor/zod/v4/core/core.js +0 -78
  88. package/dist/astgraph/vendor/zod/v4/core/doc.js +0 -35
  89. package/dist/astgraph/vendor/zod/v4/core/errors.js +0 -185
  90. package/dist/astgraph/vendor/zod/v4/core/index.js +0 -16
  91. package/dist/astgraph/vendor/zod/v4/core/json-schema-generator.js +0 -95
  92. package/dist/astgraph/vendor/zod/v4/core/json-schema-processors.js +0 -601
  93. package/dist/astgraph/vendor/zod/v4/core/json-schema.js +0 -1
  94. package/dist/astgraph/vendor/zod/v4/core/package.json +0 -7
  95. package/dist/astgraph/vendor/zod/v4/core/parse.js +0 -93
  96. package/dist/astgraph/vendor/zod/v4/core/regexes.js +0 -139
  97. package/dist/astgraph/vendor/zod/v4/core/registries.js +0 -51
  98. package/dist/astgraph/vendor/zod/v4/core/schemas.js +0 -2239
  99. package/dist/astgraph/vendor/zod/v4/core/standard-schema.js +0 -1
  100. package/dist/astgraph/vendor/zod/v4/core/to-json-schema.js +0 -448
  101. package/dist/astgraph/vendor/zod/v4/core/util.js +0 -674
  102. package/dist/astgraph/vendor/zod/v4/core/versions.js +0 -5
  103. package/dist/astgraph/vendor/zod/v4/index.js +0 -3
  104. package/dist/astgraph/vendor/zod/v4/locales/ar.js +0 -106
  105. package/dist/astgraph/vendor/zod/v4/locales/az.js +0 -105
  106. package/dist/astgraph/vendor/zod/v4/locales/be.js +0 -156
  107. package/dist/astgraph/vendor/zod/v4/locales/bg.js +0 -120
  108. package/dist/astgraph/vendor/zod/v4/locales/ca.js +0 -107
  109. package/dist/astgraph/vendor/zod/v4/locales/cs.js +0 -111
  110. package/dist/astgraph/vendor/zod/v4/locales/da.js +0 -115
  111. package/dist/astgraph/vendor/zod/v4/locales/de.js +0 -108
  112. package/dist/astgraph/vendor/zod/v4/locales/el.js +0 -109
  113. package/dist/astgraph/vendor/zod/v4/locales/en.js +0 -113
  114. package/dist/astgraph/vendor/zod/v4/locales/eo.js +0 -109
  115. package/dist/astgraph/vendor/zod/v4/locales/es.js +0 -132
  116. package/dist/astgraph/vendor/zod/v4/locales/fa.js +0 -114
  117. package/dist/astgraph/vendor/zod/v4/locales/fi.js +0 -112
  118. package/dist/astgraph/vendor/zod/v4/locales/fr-CA.js +0 -107
  119. package/dist/astgraph/vendor/zod/v4/locales/fr.js +0 -125
  120. package/dist/astgraph/vendor/zod/v4/locales/he.js +0 -214
  121. package/dist/astgraph/vendor/zod/v4/locales/hr.js +0 -122
  122. package/dist/astgraph/vendor/zod/v4/locales/hu.js +0 -108
  123. package/dist/astgraph/vendor/zod/v4/locales/hy.js +0 -147
  124. package/dist/astgraph/vendor/zod/v4/locales/id.js +0 -106
  125. package/dist/astgraph/vendor/zod/v4/locales/index.js +0 -52
  126. package/dist/astgraph/vendor/zod/v4/locales/is.js +0 -109
  127. package/dist/astgraph/vendor/zod/v4/locales/it.js +0 -108
  128. package/dist/astgraph/vendor/zod/v4/locales/ja.js +0 -107
  129. package/dist/astgraph/vendor/zod/v4/locales/ka.js +0 -112
  130. package/dist/astgraph/vendor/zod/v4/locales/kh.js +0 -5
  131. package/dist/astgraph/vendor/zod/v4/locales/km.js +0 -110
  132. package/dist/astgraph/vendor/zod/v4/locales/ko.js +0 -111
  133. package/dist/astgraph/vendor/zod/v4/locales/lt.js +0 -203
  134. package/dist/astgraph/vendor/zod/v4/locales/mk.js +0 -109
  135. package/dist/astgraph/vendor/zod/v4/locales/ms.js +0 -107
  136. package/dist/astgraph/vendor/zod/v4/locales/nl.js +0 -110
  137. package/dist/astgraph/vendor/zod/v4/locales/no.js +0 -108
  138. package/dist/astgraph/vendor/zod/v4/locales/ota.js +0 -109
  139. package/dist/astgraph/vendor/zod/v4/locales/package.json +0 -7
  140. package/dist/astgraph/vendor/zod/v4/locales/pl.js +0 -109
  141. package/dist/astgraph/vendor/zod/v4/locales/ps.js +0 -114
  142. package/dist/astgraph/vendor/zod/v4/locales/pt.js +0 -108
  143. package/dist/astgraph/vendor/zod/v4/locales/ro.js +0 -119
  144. package/dist/astgraph/vendor/zod/v4/locales/ru.js +0 -156
  145. package/dist/astgraph/vendor/zod/v4/locales/sl.js +0 -109
  146. package/dist/astgraph/vendor/zod/v4/locales/sv.js +0 -110
  147. package/dist/astgraph/vendor/zod/v4/locales/ta.js +0 -110
  148. package/dist/astgraph/vendor/zod/v4/locales/th.js +0 -110
  149. package/dist/astgraph/vendor/zod/v4/locales/tr.js +0 -105
  150. package/dist/astgraph/vendor/zod/v4/locales/ua.js +0 -5
  151. package/dist/astgraph/vendor/zod/v4/locales/uk.js +0 -108
  152. package/dist/astgraph/vendor/zod/v4/locales/ur.js +0 -110
  153. package/dist/astgraph/vendor/zod/v4/locales/uz.js +0 -110
  154. package/dist/astgraph/vendor/zod/v4/locales/vi.js +0 -108
  155. package/dist/astgraph/vendor/zod/v4/locales/yo.js +0 -107
  156. package/dist/astgraph/vendor/zod/v4/locales/zh-CN.js +0 -109
  157. package/dist/astgraph/vendor/zod/v4/locales/zh-TW.js +0 -107
  158. package/dist/astgraph/vendor/zod/v4/mini/checks.js +0 -1
  159. package/dist/astgraph/vendor/zod/v4/mini/coerce.js +0 -22
  160. package/dist/astgraph/vendor/zod/v4/mini/external.js +0 -14
  161. package/dist/astgraph/vendor/zod/v4/mini/index.js +0 -3
  162. package/dist/astgraph/vendor/zod/v4/mini/iso.js +0 -34
  163. package/dist/astgraph/vendor/zod/v4/mini/package.json +0 -7
  164. package/dist/astgraph/vendor/zod/v4/mini/parse.js +0 -1
  165. package/dist/astgraph/vendor/zod/v4/mini/schemas.js +0 -961
  166. package/dist/astgraph/vendor/zod/v4/package.json +0 -7
  167. package/dist/chunk-CIVPKHF4.js +0 -53
  168. package/dist/desktop-renderer/assets/index-CqRIr-hz.js +0 -154
  169. package/dist/devtools-4QTPKBKK.js +0 -2
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Heap watermarks for the controlled rotation protocol.
3
+ *
4
+ * Long-running sessions (interactive turns, /loop cycles, /goal rounds) rotate
5
+ * onto a fresh heap instead of growing until V8 dies. Two watermarks:
6
+ *
7
+ * - MEMORY_PRESSURE_HEAP_RATIO: hard guard checked before every model call.
8
+ * Tripping it stops the current turn; the session is persisted first.
9
+ * - MEMORY_ROTATION_HEAP_RATIO: soft guard checked only at turn/cycle/round
10
+ * boundaries. Tripping it rotates between units of work, so multi-day runs
11
+ * keep going on a fresh heap without losing the loop or goal in flight.
12
+ *
13
+ * Both readings are GC-verified when --expose-gc is available (the launcher
14
+ * injects it): heapUsed includes uncollected garbage, and declaring pressure
15
+ * on garbage alone would rotate or stop turns for no reason. A full GC before
16
+ * judging keeps the decision about the live set only.
17
+ */
18
+ export declare const MEMORY_PRESSURE_HEAP_RATIO = 0.8;
19
+ export declare const MEMORY_ROTATION_HEAP_RATIO = 0.6;
20
+ export declare const MEMORY_PRESSURE_RSS_RATIO = 0.75;
21
+ export declare const MEMORY_ROTATION_RSS_RATIO = 0.6;
22
+ export interface HeapReading {
23
+ heapUsed: number;
24
+ heapLimit: number;
25
+ ratio: number;
26
+ /** Ratio measured after a forced full GC; undefined when gc is not exposed. */
27
+ verifiedRatio?: number;
28
+ gcVerified: boolean;
29
+ rss?: number;
30
+ memoryLimit?: number;
31
+ rssRatio?: number;
32
+ external?: number;
33
+ arrayBuffers?: number;
34
+ }
35
+ export declare function readHeap(): {
36
+ heapUsed: number;
37
+ heapLimit: number;
38
+ ratio: number;
39
+ };
40
+ /**
41
+ * Hard-guard reading. Returns undefined below the threshold; when the raw
42
+ * reading crosses it, a full GC (if exposed) decides whether the live set
43
+ * really is that large. Without --expose-gc the raw reading stands.
44
+ */
45
+ export declare function verifiedHeapPressure(threshold: number): HeapReading | undefined;
46
+ /**
47
+ * Boundary rotation decision. Cheap below the precheck ratio; above it the
48
+ * live set is measured with a full GC and compared against the soft
49
+ * watermark. Without --expose-gc only a raw reading at the hard watermark
50
+ * rotates, so an uninstrumented process degrades to the old behaviour.
51
+ */
52
+ export declare function heapRotationNeeded(): HeapReading | undefined;
53
+ /**
54
+ * Explicit opt-in only. The launcher already asks V8 for one near-limit
55
+ * snapshot; synchronously taking another in the recovery path can exhaust the
56
+ * very heap/RSS headroom needed to persist and exit cleanly.
57
+ */
58
+ export declare function heapSnapshotWarranted(_reading: HeapReading): boolean;
@@ -7,23 +7,62 @@
7
7
  * relaunches the CLI with `--resume <sessionId>`, so memory pressure restores
8
8
  * the saved session instead of ending in a fatal V8 OOM crash. The interrupted
9
9
  * turn is intentionally not replayed because it may contain non-idempotent tools.
10
+ *
11
+ * Boundary rotations (between turns, /loop cycles, /goal rounds) carry a
12
+ * `continuation` in the marker: the relaunched process picks the interrupted
13
+ * loop or goal back up from its persisted state, so multi-day autonomous runs
14
+ * survive heap rotation without losing the long-running task.
10
15
  */
11
16
  export declare const MEMORY_RESTART_EXIT_CODE = 75;
12
17
  export declare const MEMORY_RESTART_MARKER_FILE = "memory-restart.json";
13
- export declare const MEMORY_RESTART_MAX_ATTEMPTS = 3;
18
+ /**
19
+ * Rotations are seamless (the session and any loop/goal resume automatically),
20
+ * so the budget only exists to stop a pathological spin: 24 rotations inside
21
+ * one hour still covers a multi-day run rotating every few hours.
22
+ */
23
+ export declare const MEMORY_RESTART_MAX_ATTEMPTS = 24;
14
24
  export declare const MEMORY_RESTART_WINDOW_MS: number;
25
+ /** Two rotations closer together than this mean the fresh heap is born heavy; stop rotating and let the hard guard decide. */
26
+ export declare const MEMORY_RESTART_MIN_GAP_MS: number;
27
+ /**
28
+ * Leave enough time for a slow launcher, host reboot, or unattended machine
29
+ * wake-up to recover a persisted long task. Session/id validation still keeps
30
+ * an unrelated stale marker from resuming in the wrong process.
31
+ */
32
+ export declare const MEMORY_RESTART_CONTINUATION_TTL_MS: number;
33
+ export interface MemoryRestartContinuation {
34
+ kind: "loop" | "goal";
35
+ id: string;
36
+ }
15
37
  export interface MemoryRestartMarker {
16
38
  sessionId: string;
39
+ /** Start of the fixed accounting window; unlike requestedAt this does not slide. */
40
+ windowStartedAt?: string;
17
41
  requestedAt: string;
18
42
  attempts: number;
43
+ continuation?: MemoryRestartContinuation;
19
44
  }
45
+ /** Recorded when a rotation is requested; orchestrators skip terminal bookkeeping on the way out. */
46
+ export declare function markMemoryRotation(): void;
47
+ export declare function memoryRotationActive(): boolean;
48
+ /** In-process hosts clear this only after the old runtime has been fully disposed. */
49
+ export declare function clearMemoryRotation(): void;
20
50
  export declare function memoryRestartMarkerPath(workspace: string): string;
21
51
  /**
22
- * Count restarts per session inside a rolling window. A marker for a
52
+ * Count restarts per session inside a fixed window. A marker for a
23
53
  * different session or an expired window starts counting from one again, so
24
54
  * a healthy long-lived session never exhausts the budget.
25
55
  */
26
- export declare function nextMemoryRestartMarker(previous: MemoryRestartMarker | undefined, sessionId: string, now: Date): MemoryRestartMarker;
56
+ export declare function nextMemoryRestartMarker(previous: MemoryRestartMarker | undefined, sessionId: string, now: Date, continuation?: MemoryRestartContinuation): MemoryRestartMarker;
57
+ /**
58
+ * Remove a consumed continuation without turning marker consumption into a
59
+ * second restart attempt or extending the accounting/cooldown windows.
60
+ */
61
+ export declare function consumedMemoryRestartMarker(marker: MemoryRestartMarker): MemoryRestartMarker;
62
+ /** True when the previous rotation for this session is too recent for another seamless one. */
63
+ export declare function rotationCooldownActive(marker: MemoryRestartMarker | undefined, sessionId: string, now: Date): boolean;
64
+ /** The continuation a relaunched process should pick up, if still fresh. */
65
+ export declare function pendingContinuation(marker: MemoryRestartMarker | undefined, sessionId: string, now: Date): MemoryRestartContinuation | undefined;
27
66
  export declare function shouldRelaunchForMemoryRestart(marker: MemoryRestartMarker | undefined): boolean;
28
67
  /**
29
68
  * Rebuild the CLI arguments for the relaunched process: drop any existing
@@ -0,0 +1,2 @@
1
+ /** POSIX callers must spawn the root in its own process group (detached=true). */
2
+ export declare function terminateProcessTree(pid: number | undefined): Promise<void>;
@@ -0,0 +1,36 @@
1
+ import type { HeapReading } from "./heap.js";
2
+ /**
3
+ * Rotation forensics. Every heap rotation leaves a retention census: each
4
+ * major in-memory holder reports its retained size, so the next recurrence
5
+ * names its own grower instead of restarting with zero evidence. A full
6
+ * .heapsnapshot accompanies rotations whose verified live set is near the
7
+ * hard limit (or every rotation under FLAVOR_HEAP_SNAPSHOT_ON_ROTATE=1).
8
+ */
9
+ export interface RotationCensusHolder {
10
+ entries?: number;
11
+ chars?: number;
12
+ bytes?: number;
13
+ }
14
+ export interface RotationCensus {
15
+ at: string;
16
+ reason: string;
17
+ sessionId: string;
18
+ heap: {
19
+ heapUsedMb: number;
20
+ heapLimitMb: number;
21
+ rawRatio: number;
22
+ verifiedRatio?: number;
23
+ gcVerified: boolean;
24
+ rssMb: number;
25
+ externalMb: number;
26
+ arrayBuffersMb: number;
27
+ memoryLimitMb?: number;
28
+ rssRatio?: number;
29
+ };
30
+ holders: Record<string, RotationCensusHolder>;
31
+ }
32
+ export declare function censusHeapBlock(reading: HeapReading): RotationCensus["heap"];
33
+ /** Best-effort: a failed census must never block the rotation itself. */
34
+ export declare function writeRotationCensus(workspace: string, census: RotationCensus): string | undefined;
35
+ /** Best-effort heap snapshot; synchronous and slow on large heaps by nature. */
36
+ export declare function writeRotationHeapSnapshot(workspace: string): string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flavor-code",
3
- "version": "1.4.0-beta.1",
3
+ "version": "1.4.0-beta.10",
4
4
  "author": "YachuanWzh",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -31,7 +31,7 @@
31
31
  "scripts": {
32
32
  "build": "npm run build:icons && npm run build:cli && npm run build:desktop",
33
33
  "build:icons": "node scripts/build-icons.mjs",
34
- "build:cli": "tsup && tsc -p tsconfig.sdk.json && node -e \"require('fs').cpSync('src/init/astgraph','dist/astgraph',{recursive:true})\"",
34
+ "build:cli": "tsup && tsc -p tsconfig.sdk.json && node scripts/assert-production-cli.mjs",
35
35
  "build:desktop": "npm run build:desktop:main && npm run build:desktop:renderer",
36
36
  "build:desktop:main": "tsup --config tsup.desktop.config.ts",
37
37
  "build:desktop:renderer": "vite build --config vite.desktop.config.ts",
@@ -52,6 +52,7 @@
52
52
  "smoke:install": "node scripts/smoke-install.mjs",
53
53
  "smoke:d2c-worker": "npm run build:desktop:main && node scripts/smoke-d2c-worker.mjs",
54
54
  "stress:context": "vitest run scripts/stress-context-memory.test.ts --reporter=verbose",
55
+ "stress:tui-memory": "npm run build:cli && node scripts/run-tui-memory-stress.mjs",
55
56
  "stress:production-memory": "npm run build:cli && node scripts/stress-production-memory.mjs",
56
57
  "evidence:crash-fix": "vitest run scripts/evidence-crash-replay.test.ts --reporter=verbose",
57
58
  "prepack": "npm run build"
@@ -405,7 +405,7 @@ sequenceDiagram
405
405
  U->>CLI: 输入 prompt
406
406
  CLI->>L: submit(prompt, signal)
407
407
 
408
- loop 每轮迭代(最多 80 轮)
408
+ loop 每轮迭代(最多 300 轮)
409
409
  L->>C: prepareForModelCall()
410
410
  C->>C: 微压缩(清理旧工具输出)
411
411
  alt 仍超阈值
@@ -560,13 +560,13 @@ FlavorConfigSchema = {
560
560
  },
561
561
  language: "zh-CN", // BCP47 语言标签
562
562
  maxIterations: {
563
- main: 10-500, // 主 Agent 迭代上限(默认 80)
564
- subagent: 10-200, // 子 Agent 迭代上限(默认 40)
563
+ main: 10-500, // 主 Agent 迭代上限(默认 300)
564
+ subagent: 10-200, // 子 Agent 迭代上限(默认 100)
565
565
  softLimitFactor: 0.8, // 软限制比例
566
- extendBy: 20 // 扩展步数
566
+ extendBy: 50 // 扩展步数
567
567
  },
568
568
  loop: {
569
- maxCycles: 20, // 每次用户授权增加的 cycle 数
569
+ maxCycles: 100, // 每次用户授权增加的 cycle 数
570
570
  maxTokens: 500_000, // 每次用户授权增加的模型 token 数
571
571
  isolation: "auto" // 只读用当前目录;改代码自动用 worktree
572
572
  },
@@ -749,8 +749,8 @@ flowchart TD
749
749
  maxTokens = 5,000,000
750
750
  5,000,000 → 确认 → 10,000,000 → 确认 → 15,000,000 → ...
751
751
 
752
- maxCycles = 20
753
- 20 → 确认 → 40 → 确认 → 60 → ...
752
+ maxCycles = 100
753
+ 100 → 确认 → 200 → 确认 → 300 → ...
754
754
  ```
755
755
 
756
756
  token 统计包括 worker 的所有模型调用以及上下文压缩模型调用;本地 Shell 验证命令不计 token。用户拒绝产生 `budget_exhausted`;非交互模式无法确认时产生 `needs_human`。预算批准记录维度、旧/新 checkpoint、当时累计用量和时间戳。
@@ -1,237 +0,0 @@
1
- // astgraph graph database — SQLite-backed node/edge graph (codegraph-inspired).
2
- // Uses node:sqlite with WAL mode so concurrent readers never block on a writer.
3
-
4
- import { mkdirSync } from "node:fs";
5
- import { dirname } from "node:path";
6
- import { DatabaseSync } from "node:sqlite";
7
-
8
- const SCHEMA = `
9
- CREATE TABLE IF NOT EXISTS schema_versions (
10
- version INTEGER PRIMARY KEY,
11
- applied_at INTEGER NOT NULL,
12
- description TEXT
13
- );
14
-
15
- CREATE TABLE IF NOT EXISTS files (
16
- path TEXT PRIMARY KEY,
17
- content_hash TEXT NOT NULL,
18
- language TEXT NOT NULL,
19
- size INTEGER NOT NULL,
20
- modified_at INTEGER NOT NULL DEFAULT 0,
21
- indexed_at INTEGER NOT NULL DEFAULT 0,
22
- node_count INTEGER NOT NULL DEFAULT 0
23
- );
24
-
25
- CREATE TABLE IF NOT EXISTS nodes (
26
- id TEXT PRIMARY KEY,
27
- kind TEXT NOT NULL,
28
- name TEXT NOT NULL,
29
- qualified_name TEXT NOT NULL,
30
- file_path TEXT NOT NULL,
31
- language TEXT NOT NULL,
32
- start_line INTEGER NOT NULL,
33
- end_line INTEGER NOT NULL,
34
- signature TEXT,
35
- docstring TEXT,
36
- is_exported INTEGER NOT NULL DEFAULT 0,
37
- is_async INTEGER NOT NULL DEFAULT 0
38
- );
39
-
40
- CREATE TABLE IF NOT EXISTS edges (
41
- id INTEGER PRIMARY KEY AUTOINCREMENT,
42
- source TEXT NOT NULL,
43
- target TEXT NOT NULL,
44
- kind TEXT NOT NULL,
45
- line INTEGER,
46
- col INTEGER,
47
- FOREIGN KEY (source) REFERENCES nodes(id) ON DELETE CASCADE,
48
- FOREIGN KEY (target) REFERENCES nodes(id) ON DELETE CASCADE
49
- );
50
-
51
- CREATE TABLE IF NOT EXISTS unresolved_refs (
52
- id INTEGER PRIMARY KEY AUTOINCREMENT,
53
- from_node_id TEXT,
54
- reference_name TEXT NOT NULL,
55
- reference_kind TEXT NOT NULL,
56
- line INTEGER NOT NULL,
57
- col INTEGER NOT NULL,
58
- file_path TEXT NOT NULL DEFAULT '',
59
- module_specifier TEXT,
60
- status TEXT NOT NULL DEFAULT 'pending',
61
- FOREIGN KEY (from_node_id) REFERENCES nodes(id) ON DELETE CASCADE
62
- );
63
-
64
- CREATE INDEX IF NOT EXISTS idx_nodes_name ON nodes(name);
65
- CREATE INDEX IF NOT EXISTS idx_nodes_lower_name ON nodes(lower(name));
66
- CREATE INDEX IF NOT EXISTS idx_nodes_file_path ON nodes(file_path);
67
- CREATE INDEX IF NOT EXISTS idx_nodes_kind ON nodes(kind);
68
- CREATE INDEX IF NOT EXISTS idx_edges_source_kind ON edges(source, kind);
69
- CREATE INDEX IF NOT EXISTS idx_edges_target_kind ON edges(target, kind);
70
- CREATE UNIQUE INDEX IF NOT EXISTS idx_edges_identity
71
- ON edges(source, target, kind, IFNULL(line, -1), IFNULL(col, -1));
72
- CREATE INDEX IF NOT EXISTS idx_unresolved_from ON unresolved_refs(from_node_id);
73
- CREATE INDEX IF NOT EXISTS idx_unresolved_name ON unresolved_refs(reference_name);
74
-
75
- CREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5(
76
- name,
77
- qualified_name,
78
- signature,
79
- docstring,
80
- content='nodes',
81
- content_rowid='rowid'
82
- );
83
-
84
- CREATE TRIGGER IF NOT EXISTS nodes_ai AFTER INSERT ON nodes BEGIN
85
- INSERT INTO nodes_fts(rowid, name, qualified_name, signature, docstring)
86
- VALUES (NEW.rowid, NEW.name, NEW.qualified_name, NEW.signature, NEW.docstring);
87
- END;
88
-
89
- CREATE TRIGGER IF NOT EXISTS nodes_ad AFTER DELETE ON nodes BEGIN
90
- INSERT INTO nodes_fts(nodes_fts, rowid, name, qualified_name, signature, docstring)
91
- VALUES ('delete', OLD.rowid, OLD.name, OLD.qualified_name, OLD.signature, OLD.docstring);
92
- END;
93
-
94
- CREATE TRIGGER IF NOT EXISTS nodes_au AFTER UPDATE ON nodes BEGIN
95
- INSERT INTO nodes_fts(nodes_fts, rowid, name, qualified_name, signature, docstring)
96
- VALUES ('delete', OLD.rowid, OLD.name, OLD.qualified_name, OLD.signature, OLD.docstring);
97
- INSERT INTO nodes_fts(rowid, name, qualified_name, signature, docstring)
98
- VALUES (NEW.rowid, NEW.name, NEW.qualified_name, NEW.signature, NEW.docstring);
99
- END;
100
-
101
- CREATE TABLE IF NOT EXISTS project_metadata (
102
- key TEXT PRIMARY KEY,
103
- value TEXT NOT NULL,
104
- updated_at INTEGER NOT NULL
105
- );
106
- `;
107
-
108
- /** Open (creating when absent) the graph database at `path`. Returns a DatabaseSync. */
109
- export function openDb(path) {
110
- if (path !== ":memory:") mkdirSync(dirname(path), { recursive: true });
111
- const db = new DatabaseSync(path);
112
- db.exec("PRAGMA journal_mode = WAL");
113
- db.exec("PRAGMA foreign_keys = ON");
114
- db.exec("PRAGMA synchronous = NORMAL");
115
- db.exec(SCHEMA);
116
- const version = db.prepare("SELECT COUNT(*) AS count FROM schema_versions").get();
117
- if (version.count === 0) {
118
- db.prepare("INSERT INTO schema_versions(version, applied_at, description) VALUES (?, ?, ?)")
119
- .run(1, Date.now(), "Initial astgraph schema");
120
- }
121
- return db;
122
- }
123
-
124
- /** Insert or replace the tracking record for one source file. */
125
- export function upsertFileRecord(db, record) {
126
- db.prepare(`
127
- INSERT INTO files(path, content_hash, language, size, modified_at, indexed_at, node_count)
128
- VALUES (?, ?, ?, ?, ?, ?, ?)
129
- ON CONFLICT(path) DO UPDATE SET
130
- content_hash = excluded.content_hash,
131
- language = excluded.language,
132
- size = excluded.size,
133
- modified_at = excluded.modified_at,
134
- indexed_at = excluded.indexed_at,
135
- node_count = excluded.node_count
136
- `).run(
137
- record.path, record.contentHash, record.language, record.size,
138
- record.modifiedAt ?? Date.now(), record.indexedAt ?? Date.now(), record.nodeCount ?? 0,
139
- );
140
- }
141
-
142
- /** Read the tracking record for one source file, or undefined when absent. */
143
- export function getFileRecord(db, path) {
144
- const row = db.prepare("SELECT * FROM files WHERE path = ?").get(path);
145
- if (row === undefined) return undefined;
146
- return {
147
- path: row.path, contentHash: row.content_hash, language: row.language,
148
- size: row.size, modifiedAt: row.modified_at, indexedAt: row.indexed_at,
149
- nodeCount: row.node_count,
150
- };
151
- }
152
-
153
- /** Delete a file record; nodes cascade (and with them edges + refs + FTS rows). */
154
- export function deleteFileRecord(db, path) {
155
- db.prepare("DELETE FROM nodes WHERE file_path = ?").run(path);
156
- db.prepare("DELETE FROM files WHERE path = ?").run(path);
157
- }
158
-
159
- /**
160
- * Replace every node belonging to a file. Runs inside one transaction; the FTS
161
- * triggers keep nodes_fts in sync.
162
- */
163
- export function replaceNodes(db, filePath, nodes) {
164
- const insert = db.prepare(`
165
- INSERT OR REPLACE INTO nodes(
166
- id, kind, name, qualified_name, file_path, language,
167
- start_line, end_line, signature, docstring, is_exported, is_async
168
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
169
- `);
170
- const clear = db.prepare("DELETE FROM nodes WHERE file_path = ?");
171
- db.exec("BEGIN");
172
- try {
173
- clear.run(filePath);
174
- for (const node of nodes) {
175
- insert.run(
176
- node.id, node.kind, node.name, node.qualifiedName, node.filePath, node.language,
177
- node.startLine, node.endLine, node.signature ?? null, node.docstring ?? null,
178
- node.isExported ? 1 : 0, node.isAsync ? 1 : 0,
179
- );
180
- }
181
- db.exec("COMMIT");
182
- } catch (error) {
183
- db.exec("ROLLBACK");
184
- throw error;
185
- }
186
- }
187
-
188
- /** Insert one edge; duplicate (source, target, kind, line, col) rows are ignored. */
189
- export function insertEdge(db, edge) {
190
- db.prepare(`
191
- INSERT OR IGNORE INTO edges(source, target, kind, line, col) VALUES (?, ?, ?, ?, ?)
192
- `).run(edge.source, edge.target, edge.kind, edge.line ?? null, edge.col ?? null);
193
- }
194
-
195
- /** Delete every edge whose source OR target belongs to a file. */
196
- export function deleteEdgesForFile(db, filePath) {
197
- db.prepare(`
198
- DELETE FROM edges WHERE source IN (SELECT id FROM nodes WHERE file_path = ?)
199
- OR target IN (SELECT id FROM nodes WHERE file_path = ?)
200
- `).run(filePath, filePath);
201
- }
202
-
203
- /** Insert one unresolved cross-file reference (status 'pending'). */
204
- export function insertUnresolvedRef(db, ref) {
205
- db.prepare(`
206
- INSERT INTO unresolved_refs(from_node_id, reference_name, reference_kind, line, col, file_path, module_specifier, status)
207
- VALUES (?, ?, ?, ?, ?, ?, ?, 'pending')
208
- `).run(ref.fromNodeId, ref.referenceName, ref.referenceKind, ref.line, ref.col, ref.filePath, ref.moduleSpecifier ?? null);
209
- }
210
-
211
- /** Delete every unresolved reference originating from a file. */
212
- export function deleteUnresolvedRefsForFile(db, filePath) {
213
- db.prepare("DELETE FROM unresolved_refs WHERE file_path = ?").run(filePath);
214
- }
215
-
216
- /** Summary counters used by /ast status. */
217
- export function stats(db) {
218
- const files = db.prepare("SELECT COUNT(*) AS count FROM files").get().count;
219
- const nodes = db.prepare("SELECT COUNT(*) AS count FROM nodes").get().count;
220
- const edges = db.prepare("SELECT COUNT(*) AS count FROM edges").get().count;
221
- const unresolved = db.prepare("SELECT COUNT(*) AS count FROM unresolved_refs WHERE status = 'pending'").get().count;
222
- return { files, nodes, edges, unresolved };
223
- }
224
-
225
- /** Store a provenance metadata value. */
226
- export function setMetadata(db, key, value) {
227
- db.prepare(`
228
- INSERT INTO project_metadata(key, value, updated_at) VALUES (?, ?, ?)
229
- ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at
230
- `).run(key, value, Date.now());
231
- }
232
-
233
- /** Read a provenance metadata value, or undefined when absent. */
234
- export function getMetadata(db, key) {
235
- const row = db.prepare("SELECT value FROM project_metadata WHERE key = ?").get(key);
236
- return row?.value;
237
- }