@bendyline/gezel-service 0.1.0 → 1.0.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.
Files changed (108) hide show
  1. package/dist/NOTICE.md +1 -1
  2. package/dist/bin/gezeld.js +51635 -50059
  3. package/dist/handboek-content/README.md +24 -2
  4. package/dist/handboek-content/conceptual/connected-apps.md +2 -0
  5. package/dist/handboek-content/technical/building-connected-apps-with-gezel-app-sdk.md +144 -0
  6. package/dist/handboek-content/technical/cli-reference.md +11 -0
  7. package/dist/handboek-content/technical/how-we-test-models.md +57 -9
  8. package/dist/handboek-content/technical/model-scorecard.md +27 -9
  9. package/dist/handboek-content/technical/npm-packages.md +67 -0
  10. package/dist/handboek-content/technical/security-model.md +18 -1
  11. package/dist/handboek-content/technical/where-files-live.md +3 -0
  12. package/dist/handboek-content/technical/writing-scripts-with-gezel-sdk.md +106 -0
  13. package/dist/handboek-content/whats-new/1.26223.md +82 -0
  14. package/dist/handboek-content/whats-new/whats-new-index.md +28 -0
  15. package/dist/handboek.d.ts +53 -26
  16. package/dist/handboek.js +103 -26
  17. package/dist/index-store/static-index-worker.js +476 -82
  18. package/dist/index.d.ts +206 -11
  19. package/dist/index.js +51615 -50051
  20. package/dist/ui/assets/{TerminalCodeEditor-CB-AXtKI.js → TerminalCodeEditor-DQICIlaI.js} +2 -2
  21. package/dist/ui/assets/{_.contribution-C6KlZ1yR.js → _.contribution-BXBGjh98.js} +1 -1
  22. package/dist/ui/assets/{chunk-6N2J7C2B-DIF7DJtk.js → chunk-6N2J7C2B-Du7clJkV.js} +1 -1
  23. package/dist/ui/assets/chunk-ILCJ3WFD-fHFoZ9wm.js +4 -0
  24. package/dist/ui/assets/{chunk-S5PCVMKU-CmFF6ff9.js → chunk-S5PCVMKU-DopU3Q9j.js} +2 -2
  25. package/dist/ui/assets/chunk-USU6HTKB-B-ElCUQS.js +1 -0
  26. package/dist/ui/assets/{chunk-WATAOG4Y-perfmDXF.js → chunk-WATAOG4Y-BnCgSncI.js} +1 -1
  27. package/dist/ui/assets/{cpp.contribution-BBBWN3Dm.js → cpp.contribution-UC-hXlnG.js} +1 -1
  28. package/dist/ui/assets/{csharp.contribution-jBA6TWhG.js → csharp.contribution-VSLdDbxa.js} +1 -1
  29. package/dist/ui/assets/{css.contribution-DQSNU6vC.js → css.contribution-DC9uQgZx.js} +1 -1
  30. package/dist/ui/assets/{cssMode-68UP_lrS.js → cssMode-DZsXawIN.js} +1 -1
  31. package/dist/ui/assets/{csv-Ctux8fO7.js → csv-RAgECoUg.js} +1 -1
  32. package/dist/ui/assets/dist-D6I_6t8i.js +195 -0
  33. package/dist/ui/assets/dist-a57vyaRu.js +2 -0
  34. package/dist/ui/assets/{doc-BdMAKGDm.js → doc-B7NXSLxH.js} +33 -23
  35. package/dist/ui/assets/{dockerfile.contribution-CSpSPKgK.js → dockerfile.contribution-PUE2MRJF.js} +1 -1
  36. package/dist/ui/assets/docx-IZY6hX8A.js +2 -0
  37. package/dist/ui/assets/{epub-oLed1tAU.js → epub-00L2M424.js} +1 -1
  38. package/dist/ui/assets/extract-UTAOG7LV-BZ_L7lLL.js +1 -0
  39. package/dist/ui/assets/{go.contribution-BjibqVfF.js → go.contribution-CsrBAk1W.js} +1 -1
  40. package/dist/ui/assets/{handlebars-Dq5dJ5WJ.js → handlebars-Bqyi6xyi.js} +1 -1
  41. package/dist/ui/assets/handlebars.contribution-C6VLDI51.js +2 -0
  42. package/dist/ui/assets/{html-fQ6X2xaa.js → html-Cgejr9YM.js} +24 -24
  43. package/dist/ui/assets/{html-Bgyk9kiZ.js → html-NLb64cMt.js} +1 -1
  44. package/dist/ui/assets/html.contribution-BP2a6izy.js +2 -0
  45. package/dist/ui/assets/{htmlMode-D5UKInqK.js → htmlMode-Utzysyes.js} +1 -1
  46. package/dist/ui/assets/{index-CPXp6BEZ.js → index-B_NFDPxp.js} +197 -195
  47. package/dist/ui/assets/index-CgP6VwNS.css +1 -0
  48. package/dist/ui/assets/infer-v-bCXeT9.js +2 -0
  49. package/dist/ui/assets/{ini.contribution-BiJ4T5K-.js → ini.contribution-CfehzoVj.js} +1 -1
  50. package/dist/ui/assets/{java.contribution-B8o1lBqP.js → java.contribution-CXk8bwAp.js} +1 -1
  51. package/dist/ui/assets/{javascript-COWkS1tr.js → javascript-BcbxETop.js} +1 -1
  52. package/dist/ui/assets/javascript.contribution-BRDuHf7J.js +2 -0
  53. package/dist/ui/assets/{jsonMode-CWWZvfzr.js → jsonMode-BORbF5qz.js} +1 -1
  54. package/dist/ui/assets/{kotlin.contribution-CxSOPQ6P.js → kotlin.contribution-CbKeqa_3.js} +1 -1
  55. package/dist/ui/assets/layouts-2A7QNF6Y-D94iKLLQ.js +1 -0
  56. package/dist/ui/assets/{less.contribution-Cthyflev.js → less.contribution-BgNGBZAo.js} +1 -1
  57. package/dist/ui/assets/{lua.contribution-894DRgPR.js → lua.contribution-CtZNsqOj.js} +1 -1
  58. package/dist/ui/assets/{markdown.contribution-d_TBTsNA.js → markdown.contribution-CNyxmHy1.js} +1 -1
  59. package/dist/ui/assets/{monaco-PebRhLpo.js → monaco-Ryh-SF_b.js} +3 -3
  60. package/dist/ui/assets/{monaco-base-4S0M5BiY.js → monaco-base-C-4W0je-.js} +1 -1
  61. package/dist/ui/assets/{monaco-setup-7hp0Z9jn.js → monaco-setup-BW0DQ8MV.js} +1 -1
  62. package/dist/ui/assets/{monaco.contribution-DQjPk7Rx.js → monaco.contribution-279M9-Uu.js} +2 -2
  63. package/dist/ui/assets/{monaco.contribution-CKDvyGVE.js → monaco.contribution-Bu1oyef5.js} +2 -2
  64. package/dist/ui/assets/{monaco.contribution-BL_zgiu2.js → monaco.contribution-C57BAnnI.js} +2 -2
  65. package/dist/ui/assets/{monaco.contribution-D61txvUB.js → monaco.contribution-o3cuP4Wp.js} +2 -2
  66. package/dist/ui/assets/{pdf-CwJ6ZJmB.js → pdf-66KslaXf.js} +1 -1
  67. package/dist/ui/assets/{php.contribution-B8kn8QoR.js → php.contribution-BulxzIpe.js} +1 -1
  68. package/dist/ui/assets/pptx-CsdVR0xn.js +6 -0
  69. package/dist/ui/assets/{python-CHygH1eM.js → python-D4zGC71G.js} +1 -1
  70. package/dist/ui/assets/python.contribution-CDI1t73R.js +2 -0
  71. package/dist/ui/assets/{ruby.contribution-BQdPKFM2.js → ruby.contribution-DVOdhLt8.js} +1 -1
  72. package/dist/ui/assets/{rust.contribution-D7wKqShc.js → rust.contribution-DLR9kg2m.js} +1 -1
  73. package/dist/ui/assets/{scss.contribution-kSTLMoty.js → scss.contribution-CYIIxBxH.js} +1 -1
  74. package/dist/ui/assets/{shell.contribution-BQnT3BBJ.js → shell.contribution-D0KjHQ5E.js} +1 -1
  75. package/dist/ui/assets/{sql.contribution-C9z55nWb.js → sql.contribution-CKhLelqr.js} +1 -1
  76. package/dist/ui/assets/{swift.contribution-BZoW5ZZj.js → swift.contribution-DiAAMfJp.js} +1 -1
  77. package/dist/ui/assets/{terminal-monaco-setup-DbSXji0d.js → terminal-monaco-setup-Dhxpm7Z8.js} +1 -1
  78. package/dist/ui/assets/{tsMode-jPpKNC6E.js → tsMode-DFEqg3P9.js} +1 -1
  79. package/dist/ui/assets/{typescript-Djn_8BHF.js → typescript-X_x8S3Dp.js} +1 -1
  80. package/dist/ui/assets/typescript.contribution-jI3BakLa.js +2 -0
  81. package/dist/ui/assets/xlsx-CdLmEC42.js +4 -0
  82. package/dist/ui/assets/{xml-DmE4Aqa-.js → xml-ANmRi8ZZ.js} +1 -1
  83. package/dist/ui/assets/xml.contribution-D5t83zAi.js +2 -0
  84. package/dist/ui/assets/{yaml-BjmK3C-c.js → yaml-R4WpJved.js} +1 -1
  85. package/dist/ui/assets/yaml.contribution-DV8dAjKa.js +2 -0
  86. package/dist/ui/index.html +15 -15
  87. package/package.json +13 -15
  88. package/dist/postinstall.d.ts +0 -2
  89. package/dist/postinstall.js +0 -40
  90. package/dist/ui/assets/chunk-ILCJ3WFD-uwKSpQd8.js +0 -4
  91. package/dist/ui/assets/chunk-USU6HTKB-hbaA8KyS.js +0 -1
  92. package/dist/ui/assets/dist-i9jV8CX8.js +0 -2
  93. package/dist/ui/assets/dist-jh33rACm.js +0 -195
  94. package/dist/ui/assets/docx-CNW-xqHT.js +0 -2
  95. package/dist/ui/assets/extract-UTAOG7LV-WxmEnrrc.js +0 -1
  96. package/dist/ui/assets/handlebars.contribution-DDSQBNPu.js +0 -2
  97. package/dist/ui/assets/html.contribution-DrClfj2L.js +0 -2
  98. package/dist/ui/assets/index-Caz-FRQy.css +0 -1
  99. package/dist/ui/assets/infer-Cc7ks6NX.js +0 -2
  100. package/dist/ui/assets/javascript.contribution-DMEzq0y4.js +0 -2
  101. package/dist/ui/assets/layouts-2A7QNF6Y-DR7-KboS.js +0 -1
  102. package/dist/ui/assets/pptx-Bmj2v9CT.js +0 -6
  103. package/dist/ui/assets/python.contribution-CmwCxp-v.js +0 -2
  104. package/dist/ui/assets/typescript.contribution-D4JmB9tz.js +0 -2
  105. package/dist/ui/assets/xlsx-BCnO44v8.js +0 -4
  106. package/dist/ui/assets/xml.contribution-BepqhMeK.js +0 -2
  107. package/dist/ui/assets/yaml.contribution-BwT8qEVt.js +0 -2
  108. package/postinstall.mjs +0 -8
package/dist/index.d.ts CHANGED
@@ -289,6 +289,15 @@ interface ProjectFindingLifecycleEntry {
289
289
  type ProjectFindingLifecycle = Record<string, ProjectFindingLifecycleEntry>;
290
290
  interface StoreOptions {
291
291
  home: string;
292
+ /**
293
+ * Whether `home` is private to one OS user. On Unix these homes are created
294
+ * and repaired as 0700 so ordinary 0644 state files remain unreachable to
295
+ * other local accounts. System/machine homes must opt out because their
296
+ * installer-managed runtime discovery is intentionally shared.
297
+ *
298
+ * Defaults to true. Production system-scope stores opt out explicitly.
299
+ */
300
+ privateUserHome?: boolean;
292
301
  /**
293
302
  * Optional history recorder. When set, the Store emits audit events after
294
303
  * successful writes (create/rename/update/delete for gezels + projects +
@@ -348,6 +357,8 @@ declare class Store {
348
357
  private readonly external?;
349
358
  /** True for a `machine-engine` broker: engines and models, no product state. */
350
359
  private readonly engineOnly;
360
+ /** Whether the Store owns a home private to the current OS account. */
361
+ private readonly privateUserHome;
351
362
  private readonly poppetjes;
352
363
  private readonly documents;
353
364
  private readonly artifacts;
@@ -2589,10 +2600,18 @@ interface ProviderUsage {
2589
2600
  quotaBuckets: QuotaBucket[];
2590
2601
  todayTurns: number;
2591
2602
  todayTokensIn: number;
2603
+ /**
2604
+ * Portion of `todayTokensIn` the provider reported as prompt-cache reads.
2605
+ * Zero both when nothing was cached and when the provider reports no
2606
+ * breakdown (e.g. Copilot) — absence of data and absence of hits are
2607
+ * indistinguishable here, so render 0 as "no cache info", not "0% hit".
2608
+ */
2609
+ todayTokensCached: number;
2592
2610
  todayTokensOut: number;
2593
2611
  todayCost: number;
2594
2612
  totalTurns: number;
2595
2613
  totalTokensIn: number;
2614
+ totalTokensCached: number;
2596
2615
  totalTokensOut: number;
2597
2616
  totalCost: number;
2598
2617
  /**
@@ -2844,7 +2863,7 @@ declare class ProviderQueue {
2844
2863
  private readonly affinityWindowMs;
2845
2864
  private readonly maxWaitMs;
2846
2865
  /** See {@link ProviderQueueOptions.ambientQuietMs}. 0 = gate off. */
2847
- private readonly ambientQuietMs;
2866
+ readonly ambientQuietMs: number;
2848
2867
  /**
2849
2868
  * Last time NON-ambient work touched this queue (enqueue, dispatch,
2850
2869
  * or release — any lane). Initialized to construction time so a
@@ -4853,16 +4872,47 @@ declare class ModelFitnessManager {
4853
4872
  }
4854
4873
 
4855
4874
  /**
4856
- * Per-file semantic enrichment (the boekwachter's unit of work): produce an
4857
- * optional one-paragraph summary via a local LLM, build embeddable chunks, and
4858
- * store their vectors. Embeddings run locally (transformers.js) and are the
4859
- * always-on part; the LLM summary is best-effort (skipped when no local model
4860
- * is configured). Hash-gated by the caller via `filesNeedingEnrichment`.
4875
+ * Who produced an LLM-written index row. Output-only bookkeeping never an
4876
+ * input to model routing. Absent fields stay NULL (rows written before the
4877
+ * v10 migration, or deps built without a boekwachter) and renderers degrade
4878
+ * to whatever segments exist.
4879
+ */
4880
+ interface IndexProvenance {
4881
+ provider?: string;
4882
+ gezelId?: string;
4883
+ gezelName?: string;
4884
+ appVersion?: string;
4885
+ }
4886
+
4887
+ /**
4888
+ * AI-shadow producers: the second shadow-tree producer class. Office docs get
4889
+ * deterministic squisq conversions in the STATIC pass; images and audio need
4890
+ * a model — a vision description (+OCR) or an STT transcript — so they run in
4891
+ * the idle-gated AI tier instead, writing the same
4892
+ * `artifacts/shadow/<parent>/<basename>_files/<stem>.md` layout with a YAML
4893
+ * frontmatter header carrying source hash + provenance.
4861
4894
  *
4862
- * Deps are injected so this is unit-testable without a real model:
4863
- * - `summarize(prompt)` summary text, or '' to skip (e.g. no LLM)
4864
- * - `embed(texts)` → one vector per text
4895
+ * The sidecar is the artifact; `shadow_state` is only the work gate. The
4896
+ * frontmatter's `source_hash` makes the file self-describing: a rebuilt DB
4897
+ * (home-fallback flip, deleted index) re-adopts a fresh sidecar without
4898
+ * re-paying the model call.
4865
4899
  */
4900
+ interface AiShadowProducers {
4901
+ /** Absolute image path → markdown body (description + OCR), null when unavailable. */
4902
+ describeImage?: (absPath: string) => Promise<{
4903
+ body: string;
4904
+ model?: string;
4905
+ } | null>;
4906
+ /** Absolute audio path → markdown transcript body, null when unavailable. */
4907
+ transcribeAudio?: (absPath: string) => Promise<{
4908
+ body: string;
4909
+ model?: string;
4910
+ } | null>;
4911
+ }
4912
+ interface AiShadowDeps extends AiShadowProducers {
4913
+ provenance?: IndexProvenance;
4914
+ }
4915
+
4866
4916
  interface EnrichDeps {
4867
4917
  summarize: (prompt: string) => Promise<string>;
4868
4918
  embed: (texts: string[]) => Promise<number[][]>;
@@ -4874,6 +4924,20 @@ interface EnrichDeps {
4874
4924
  * configured; the review pass skips entirely then.
4875
4925
  */
4876
4926
  review?: (prompt: string) => Promise<string>;
4927
+ /**
4928
+ * Stamped onto every row this deps object writes. Built once in
4929
+ * `buildEnrichDeps` from the SAME resolved target that builds the
4930
+ * completions, so it reflects reality (env overrides, Night Shift) —
4931
+ * output-only, never a routing input.
4932
+ */
4933
+ provenance?: IndexProvenance;
4934
+ /**
4935
+ * Live concurrent-one-shot width of the resolved target's queue. Full
4936
+ * drives dispatch this many per-file scans at once instead of one; the
4937
+ * value is re-read as slots free because a lazily-initialized provider
4938
+ * reports 1 until its first call spins it up.
4939
+ */
4940
+ oneShotWidth?: () => number;
4877
4941
  }
4878
4942
 
4879
4943
  interface AreaPassResult {
@@ -4897,6 +4961,24 @@ interface ResolvedRubric {
4897
4961
  source: 'builtin' | 'override';
4898
4962
  }
4899
4963
 
4964
+ /**
4965
+ * Pool options for the AI passes. `concurrency` is the live width of the
4966
+ * summarizer target's queue (full drives pass it; background stays serial).
4967
+ * `drain` switches a call from "one fixed batch" to "run to empty": the
4968
+ * work-list is re-queried as slots open so the pool never sits idle at a
4969
+ * batch tail. `shouldStop` (the indexing job's pause switch) is checked and
4970
+ * `onProgress` fired at each refill — the same cadence the caller's old
4971
+ * per-batch loop provided.
4972
+ */
4973
+ interface EnrichDriveOpts {
4974
+ concurrency?: () => number;
4975
+ drain?: {
4976
+ shouldStop?: () => Promise<boolean> | boolean;
4977
+ onProgress?: (progress: {
4978
+ files: number;
4979
+ }) => void;
4980
+ };
4981
+ }
4900
4982
  declare class ContentIndex {
4901
4983
  private readonly store;
4902
4984
  private readonly home;
@@ -4974,13 +5056,26 @@ declare class ContentIndex {
4974
5056
  summarized: number;
4975
5057
  embedded: number;
4976
5058
  pending: number;
5059
+ skipped: number;
5060
+ shadowsPending: number;
4977
5061
  embedModel?: string;
4978
5062
  } | null>;
4979
- enrich(projectId: string, deps: EnrichDeps, limit?: number): Promise<{
5063
+ enrich(projectId: string, deps: EnrichDeps, limit?: number, opts?: EnrichDriveOpts): Promise<{
4980
5064
  files: number;
4981
5065
  summarized: number;
4982
5066
  embedded: number;
4983
5067
  } | null>;
5068
+ /**
5069
+ * Run one batch of the AI-shadow tier: describe images / transcribe audio
5070
+ * into `artifacts/shadow/` sidecars. Runs BEFORE the summary tier so a
5071
+ * produced shadow immediately joins the enrichment work-list. No-op when
5072
+ * neither producer is wired (no vision model / no STT configured).
5073
+ */
5074
+ aiShadows(projectId: string, deps: AiShadowDeps, limit?: number): Promise<{
5075
+ files: number;
5076
+ produced: number;
5077
+ called: number;
5078
+ } | null>;
4984
5079
  /**
4985
5080
  * Cheap existence probe — true when a content index db is on disk for
4986
5081
  * this project. File-stat only; never opens (an open would CREATE the
@@ -5008,7 +5103,7 @@ declare class ContentIndex {
5008
5103
  * whole night budget in timeouts). Rubrics can be injected (one resolve per
5009
5104
  * manager tick; also the test seam). Null when no index exists.
5010
5105
  */
5011
- review(projectId: string, deps: EnrichDeps, limit?: number, rubrics?: Map<string, ResolvedRubric>): Promise<{
5106
+ review(projectId: string, deps: EnrichDeps, limit?: number, rubrics?: Map<string, ResolvedRubric>, opts?: EnrichDriveOpts): Promise<{
5012
5107
  files: number;
5013
5108
  reviewed: number;
5014
5109
  } | null>;
@@ -10229,6 +10324,15 @@ declare class ChatManager {
10229
10324
  }): Promise<ProviderName>;
10230
10325
  /** Return the provider if it has already been initialized; never creates one. */
10231
10326
  getProviderIfReady(name: ProviderName): LLMProvider | null;
10327
+ /**
10328
+ * Concurrent one-shot width for a provider: its queue's configured
10329
+ * concurrency once initialized (singleton or pooled local engine), else 1.
10330
+ * Bulk callers (index drives) dispatch width-many one-shots to keep the
10331
+ * queue full — the queue still arbitrates its interactive/background lanes.
10332
+ * Live value: an uninitialized provider reports 1 and widens after the
10333
+ * first call spins it up, so callers should re-read between dispatches.
10334
+ */
10335
+ oneShotQueueWidth(name: ProviderName): number;
10232
10336
  /**
10233
10337
  * Snapshot of the Claude CLI worker pool, enriched with gezel + project
10234
10338
  * display names so the UI pill can render "Maya · Atari Adventure
@@ -11924,6 +12028,13 @@ interface TaskRunnerOptions {
11924
12028
  * to "always pending" (only the active-shift gate applies).
11925
12029
  */
11926
12030
  isNightShiftPending?: (task: Task) => boolean;
12031
+ /**
12032
+ * True while the night-shift index catch-up sweep runs. Night-shift
12033
+ * handoffs stay held on the queue until it finishes, so batch work starts
12034
+ * against a current static + AI index instead of racing the indexer for
12035
+ * the engine. Defaults to never-active.
12036
+ */
12037
+ isIndexCatchUpActive?: () => boolean;
11927
12038
  }
11928
12039
  declare class TaskRunner {
11929
12040
  private readonly store;
@@ -11932,6 +12043,7 @@ declare class TaskRunner {
11932
12043
  private readonly now;
11933
12044
  private readonly isNightShiftActive;
11934
12045
  private readonly isNightShiftPending;
12046
+ private readonly isIndexCatchUpActive;
11935
12047
  private readonly pending;
11936
12048
  private readonly activeDispatches;
11937
12049
  private nextId;
@@ -12108,6 +12220,13 @@ declare class WorkspaceIndexManager {
12108
12220
  * - on-mount of the Commands panel when status is `never`
12109
12221
  */
12110
12222
  refresh(projectId: string): Promise<WorkspaceIndexStatus>;
12223
+ /**
12224
+ * Like {@link refresh}, but awaits the whole scan (structural pass + the
12225
+ * content-index refresh it drives). For callers that sequence work on a
12226
+ * CURRENT index — the on-demand enrichment drive and the night-shift
12227
+ * catch-up must not summarize/review against yesterday's file list.
12228
+ */
12229
+ refreshAndWait(projectId: string): Promise<WorkspaceIndexStatus>;
12111
12230
  /**
12112
12231
  * Periodic tick: pick the highest-priority stale project and index
12113
12232
  * exactly one. One project per tick keeps the loop bounded; with a
@@ -12599,6 +12718,39 @@ interface IndexEnrichmentManagerOptions {
12599
12718
  events?: Pick<ChatEventBus, 'publishGlobalEvent'>;
12600
12719
  /** Test seam; production resolves the role from each project's roster. */
12601
12720
  resolveBoekwachter?: (projectId: string) => Promise<GezelDetail | null>;
12721
+ /**
12722
+ * AI-shadow producers (vision describe / STT transcribe). Absent when the
12723
+ * install has neither capability; the shadow tier is skipped entirely then.
12724
+ */
12725
+ shadowProducers?: AiShadowProducers;
12726
+ /** Audit log for the once-per-wave `project.index.reviewed` drain event. */
12727
+ history?: {
12728
+ log: (event: Omit<HistoryEvent, 'id' | 'at'> & {
12729
+ at?: string;
12730
+ id?: string;
12731
+ }) => Promise<void>;
12732
+ };
12733
+ /**
12734
+ * Awaitable structural refresh (WorkspaceIndexManager.refreshAndWait) run
12735
+ * at the head of every drive so the AI tiers see current files. When
12736
+ * absent (tests), the drive falls back to `contentIndex.refresh` directly.
12737
+ */
12738
+ refreshStatic?: (projectId: string) => Promise<unknown>;
12739
+ }
12740
+ /**
12741
+ * On-demand drive intensity:
12742
+ * - `background` — start now (skip the idle wait) but stay polite: ambient
12743
+ * one-shots that the local engine holds behind live chat, day-size
12744
+ * batches.
12745
+ * - `full` — occupy the engine: non-ambient one-shots that compete like any
12746
+ * interactive work, night-size batches, run to drain without yielding.
12747
+ * Both honor the indexing job's pause switch between batches.
12748
+ */
12749
+ type DriveIntensity = 'background' | 'full';
12750
+ interface DriveOptions {
12751
+ intensity: DriveIntensity;
12752
+ /** Run the review tier after summaries drain (default true). */
12753
+ reviews?: boolean;
12602
12754
  }
12603
12755
  declare class IndexEnrichmentManager {
12604
12756
  private readonly store;
@@ -12612,6 +12764,13 @@ declare class IndexEnrichmentManager {
12612
12764
  private readonly isPaused;
12613
12765
  private readonly events;
12614
12766
  private readonly resolveBoekwachter;
12767
+ private readonly shadowProducers;
12768
+ private readonly history;
12769
+ private readonly refreshStatic;
12770
+ /** In-flight on-demand drives, one per project (joiners get the same run). */
12771
+ private readonly drives;
12772
+ /** Nonzero while a night-shift catch-up sweep is holding task dispatch. */
12773
+ private catchUpRuns;
12615
12774
  private startupTimer;
12616
12775
  private tickTimer;
12617
12776
  private running;
@@ -12621,6 +12780,42 @@ declare class IndexEnrichmentManager {
12621
12780
  stop(): void;
12622
12781
  /** Live, durable-for-the-tick status consumed by the Night Shift menu. */
12623
12782
  getActivity(): IndexEnrichmentActivity | null;
12783
+ /**
12784
+ * Emit the once-per-wave `project.index.reviewed` audit event: only on the
12785
+ * transition where this tick stored reviews AND the queue is now empty.
12786
+ * Per-file events would flood the ~150-kind flat log (day batches alone
12787
+ * would emit dozens per sweep); the drain is the meaningful moment.
12788
+ */
12789
+ private logReviewDrain;
12790
+ /**
12791
+ * True while a night-shift catch-up sweep runs — the TaskRunner holds
12792
+ * night-shift task dispatch on it so batch work starts against a current
12793
+ * index, per the explicit "index first, then tasks" activation contract.
12794
+ */
12795
+ isCatchUpActive(): boolean;
12796
+ /** True while an on-demand drive is running (optionally for one project). */
12797
+ isDriving(projectId?: string): boolean;
12798
+ /** Mode of the drive running for a project, or null when idle. */
12799
+ driveMode(projectId: string): DriveIntensity | null;
12800
+ /**
12801
+ * Start an on-demand drive for one project: static refresh first, then the
12802
+ * AI tiers (shadows → summaries → areas → reviews) to drain. Returns
12803
+ * immediately; progress flows over the usual `index_progress` events and
12804
+ * `/index/status` polling. One drive per project — a second request joins
12805
+ * the running one.
12806
+ */
12807
+ drive(projectId: string, opts: DriveOptions): {
12808
+ started: boolean;
12809
+ alreadyRunning: boolean;
12810
+ };
12811
+ /**
12812
+ * Bring every indexing-enabled project's static AND AI index up to date,
12813
+ * sequentially at full intensity — the night-shift activation sweep. The
12814
+ * catch-up flag is raised synchronously so a caller that kicks this (not
12815
+ * awaited) and then wakes the TaskRunner still gets the dispatch hold.
12816
+ */
12817
+ catchUpAll(): Promise<void>;
12818
+ private runDrive;
12624
12819
  /** Exposed for tests: run one batch ignoring the timers (still idle-gated). */
12625
12820
  tick(): Promise<void>;
12626
12821
  private isIdle;