@cortexkit/opencode-magic-context 0.2.9 → 0.3.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 (43) hide show
  1. package/README.md +17 -4
  2. package/dist/agents/magic-context-prompt.d.ts +1 -1
  3. package/dist/agents/magic-context-prompt.d.ts.map +1 -1
  4. package/dist/cli/setup.d.ts.map +1 -1
  5. package/dist/cli.js +38 -3
  6. package/dist/config/schema/magic-context.d.ts +3 -0
  7. package/dist/config/schema/magic-context.d.ts.map +1 -1
  8. package/dist/features/magic-context/dreamer/runner.d.ts.map +1 -1
  9. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  10. package/dist/features/magic-context/storage-meta-persisted.d.ts +2 -0
  11. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  12. package/dist/features/magic-context/storage-meta-shared.d.ts +1 -0
  13. package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
  14. package/dist/features/magic-context/storage-meta.d.ts +1 -1
  15. package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
  16. package/dist/features/magic-context/storage-smart-notes.d.ts +24 -0
  17. package/dist/features/magic-context/storage-smart-notes.d.ts.map +1 -0
  18. package/dist/features/magic-context/storage.d.ts +2 -1
  19. package/dist/features/magic-context/storage.d.ts.map +1 -1
  20. package/dist/features/magic-context/types.d.ts +1 -0
  21. package/dist/features/magic-context/types.d.ts.map +1 -1
  22. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  23. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  24. package/dist/hooks/magic-context/note-nudger.d.ts +1 -1
  25. package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -1
  26. package/dist/hooks/magic-context/strip-content.d.ts +12 -0
  27. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  28. package/dist/hooks/magic-context/system-prompt-hash.d.ts +5 -0
  29. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  30. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  31. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  32. package/dist/index.js +634 -123
  33. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  34. package/dist/plugin/tool-registry.d.ts.map +1 -1
  35. package/dist/tools/ctx-note/constants.d.ts +1 -1
  36. package/dist/tools/ctx-note/constants.d.ts.map +1 -1
  37. package/dist/tools/ctx-note/tools.d.ts +2 -0
  38. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  39. package/dist/tools/ctx-note/types.d.ts +3 -1
  40. package/dist/tools/ctx-note/types.d.ts.map +1 -1
  41. package/package.json +4 -3
  42. package/LICENSE +0 -21
  43. package/scripts/install.sh +0 -35
package/dist/index.js CHANGED
@@ -144,7 +144,7 @@ function detectConfigFile(basePath) {
144
144
  return { format: "none", path: jsoncPath };
145
145
  }
146
146
 
147
- // node_modules/zod/v4/classic/external.js
147
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
148
148
  var exports_external = {};
149
149
  __export(exports_external, {
150
150
  xor: () => xor,
@@ -385,7 +385,7 @@ __export(exports_external, {
385
385
  $brand: () => $brand
386
386
  });
387
387
 
388
- // node_modules/zod/v4/core/index.js
388
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/index.js
389
389
  var exports_core2 = {};
390
390
  __export(exports_core2, {
391
391
  version: () => version,
@@ -663,7 +663,7 @@ __export(exports_core2, {
663
663
  $ZodAny: () => $ZodAny
664
664
  });
665
665
 
666
- // node_modules/zod/v4/core/core.js
666
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/core.js
667
667
  var NEVER = Object.freeze({
668
668
  status: "aborted"
669
669
  });
@@ -739,7 +739,7 @@ function config(newConfig) {
739
739
  Object.assign(globalConfig, newConfig);
740
740
  return globalConfig;
741
741
  }
742
- // node_modules/zod/v4/core/util.js
742
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/util.js
743
743
  var exports_util = {};
744
744
  __export(exports_util, {
745
745
  unwrapMessage: () => unwrapMessage,
@@ -1413,7 +1413,7 @@ class Class {
1413
1413
  constructor(..._args) {}
1414
1414
  }
1415
1415
 
1416
- // node_modules/zod/v4/core/errors.js
1416
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/errors.js
1417
1417
  var initializer = (inst, def) => {
1418
1418
  inst.name = "$ZodError";
1419
1419
  Object.defineProperty(inst, "_zod", {
@@ -1550,7 +1550,7 @@ function prettifyError(error) {
1550
1550
  `);
1551
1551
  }
1552
1552
 
1553
- // node_modules/zod/v4/core/parse.js
1553
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/parse.js
1554
1554
  var _parse = (_Err) => (schema, value, _ctx, _params) => {
1555
1555
  const ctx = _ctx ? Object.assign(_ctx, { async: false }) : { async: false };
1556
1556
  const result = schema._zod.run({ value, issues: [] }, ctx);
@@ -1637,7 +1637,7 @@ var _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
1637
1637
  return _safeParseAsync(_Err)(schema, value, _ctx);
1638
1638
  };
1639
1639
  var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync($ZodRealError);
1640
- // node_modules/zod/v4/core/regexes.js
1640
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/regexes.js
1641
1641
  var exports_regexes = {};
1642
1642
  __export(exports_regexes, {
1643
1643
  xid: () => xid,
@@ -1794,7 +1794,7 @@ var sha512_hex = /^[0-9a-fA-F]{128}$/;
1794
1794
  var sha512_base64 = /* @__PURE__ */ fixedBase64(86, "==");
1795
1795
  var sha512_base64url = /* @__PURE__ */ fixedBase64url(86);
1796
1796
 
1797
- // node_modules/zod/v4/core/checks.js
1797
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/checks.js
1798
1798
  var $ZodCheck = /* @__PURE__ */ $constructor("$ZodCheck", (inst, def) => {
1799
1799
  var _a;
1800
1800
  inst._zod ?? (inst._zod = {});
@@ -2341,7 +2341,7 @@ var $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (ins
2341
2341
  };
2342
2342
  });
2343
2343
 
2344
- // node_modules/zod/v4/core/doc.js
2344
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/doc.js
2345
2345
  class Doc {
2346
2346
  constructor(args = []) {
2347
2347
  this.content = [];
@@ -2379,14 +2379,14 @@ class Doc {
2379
2379
  }
2380
2380
  }
2381
2381
 
2382
- // node_modules/zod/v4/core/versions.js
2382
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/versions.js
2383
2383
  var version = {
2384
2384
  major: 4,
2385
2385
  minor: 3,
2386
2386
  patch: 6
2387
2387
  };
2388
2388
 
2389
- // node_modules/zod/v4/core/schemas.js
2389
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/schemas.js
2390
2390
  var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
2391
2391
  var _a;
2392
2392
  inst ?? (inst = {});
@@ -4348,7 +4348,7 @@ function handleRefineResult(result, payload, input, inst) {
4348
4348
  payload.issues.push(issue(_iss));
4349
4349
  }
4350
4350
  }
4351
- // node_modules/zod/v4/locales/index.js
4351
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/index.js
4352
4352
  var exports_locales = {};
4353
4353
  __export(exports_locales, {
4354
4354
  zhTW: () => zh_TW_default,
@@ -4402,7 +4402,7 @@ __export(exports_locales, {
4402
4402
  ar: () => ar_default
4403
4403
  });
4404
4404
 
4405
- // node_modules/zod/v4/locales/ar.js
4405
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ar.js
4406
4406
  var error = () => {
4407
4407
  const Sizable = {
4408
4408
  string: { unit: "\u062D\u0631\u0641", verb: "\u0623\u0646 \u064A\u062D\u0648\u064A" },
@@ -4508,7 +4508,7 @@ function ar_default() {
4508
4508
  localeError: error()
4509
4509
  };
4510
4510
  }
4511
- // node_modules/zod/v4/locales/az.js
4511
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/az.js
4512
4512
  var error2 = () => {
4513
4513
  const Sizable = {
4514
4514
  string: { unit: "simvol", verb: "olmal\u0131d\u0131r" },
@@ -4613,7 +4613,7 @@ function az_default() {
4613
4613
  localeError: error2()
4614
4614
  };
4615
4615
  }
4616
- // node_modules/zod/v4/locales/be.js
4616
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/be.js
4617
4617
  function getBelarusianPlural(count, one, few, many) {
4618
4618
  const absCount = Math.abs(count);
4619
4619
  const lastDigit = absCount % 10;
@@ -4769,7 +4769,7 @@ function be_default() {
4769
4769
  localeError: error3()
4770
4770
  };
4771
4771
  }
4772
- // node_modules/zod/v4/locales/bg.js
4772
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/bg.js
4773
4773
  var error4 = () => {
4774
4774
  const Sizable = {
4775
4775
  string: { unit: "\u0441\u0438\u043C\u0432\u043E\u043B\u0430", verb: "\u0434\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430" },
@@ -4889,7 +4889,7 @@ function bg_default() {
4889
4889
  localeError: error4()
4890
4890
  };
4891
4891
  }
4892
- // node_modules/zod/v4/locales/ca.js
4892
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ca.js
4893
4893
  var error5 = () => {
4894
4894
  const Sizable = {
4895
4895
  string: { unit: "car\xE0cters", verb: "contenir" },
@@ -4996,7 +4996,7 @@ function ca_default() {
4996
4996
  localeError: error5()
4997
4997
  };
4998
4998
  }
4999
- // node_modules/zod/v4/locales/cs.js
4999
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/cs.js
5000
5000
  var error6 = () => {
5001
5001
  const Sizable = {
5002
5002
  string: { unit: "znak\u016F", verb: "m\xEDt" },
@@ -5107,7 +5107,7 @@ function cs_default() {
5107
5107
  localeError: error6()
5108
5108
  };
5109
5109
  }
5110
- // node_modules/zod/v4/locales/da.js
5110
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/da.js
5111
5111
  var error7 = () => {
5112
5112
  const Sizable = {
5113
5113
  string: { unit: "tegn", verb: "havde" },
@@ -5222,7 +5222,7 @@ function da_default() {
5222
5222
  localeError: error7()
5223
5223
  };
5224
5224
  }
5225
- // node_modules/zod/v4/locales/de.js
5225
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/de.js
5226
5226
  var error8 = () => {
5227
5227
  const Sizable = {
5228
5228
  string: { unit: "Zeichen", verb: "zu haben" },
@@ -5330,7 +5330,7 @@ function de_default() {
5330
5330
  localeError: error8()
5331
5331
  };
5332
5332
  }
5333
- // node_modules/zod/v4/locales/en.js
5333
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/en.js
5334
5334
  var error9 = () => {
5335
5335
  const Sizable = {
5336
5336
  string: { unit: "characters", verb: "to have" },
@@ -5436,7 +5436,7 @@ function en_default() {
5436
5436
  localeError: error9()
5437
5437
  };
5438
5438
  }
5439
- // node_modules/zod/v4/locales/eo.js
5439
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/eo.js
5440
5440
  var error10 = () => {
5441
5441
  const Sizable = {
5442
5442
  string: { unit: "karaktrojn", verb: "havi" },
@@ -5545,7 +5545,7 @@ function eo_default() {
5545
5545
  localeError: error10()
5546
5546
  };
5547
5547
  }
5548
- // node_modules/zod/v4/locales/es.js
5548
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/es.js
5549
5549
  var error11 = () => {
5550
5550
  const Sizable = {
5551
5551
  string: { unit: "caracteres", verb: "tener" },
@@ -5677,7 +5677,7 @@ function es_default() {
5677
5677
  localeError: error11()
5678
5678
  };
5679
5679
  }
5680
- // node_modules/zod/v4/locales/fa.js
5680
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/fa.js
5681
5681
  var error12 = () => {
5682
5682
  const Sizable = {
5683
5683
  string: { unit: "\u06A9\u0627\u0631\u0627\u06A9\u062A\u0631", verb: "\u062F\u0627\u0634\u062A\u0647 \u0628\u0627\u0634\u062F" },
@@ -5791,7 +5791,7 @@ function fa_default() {
5791
5791
  localeError: error12()
5792
5792
  };
5793
5793
  }
5794
- // node_modules/zod/v4/locales/fi.js
5794
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/fi.js
5795
5795
  var error13 = () => {
5796
5796
  const Sizable = {
5797
5797
  string: { unit: "merkki\xE4", subject: "merkkijonon" },
@@ -5903,7 +5903,7 @@ function fi_default() {
5903
5903
  localeError: error13()
5904
5904
  };
5905
5905
  }
5906
- // node_modules/zod/v4/locales/fr.js
5906
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/fr.js
5907
5907
  var error14 = () => {
5908
5908
  const Sizable = {
5909
5909
  string: { unit: "caract\xE8res", verb: "avoir" },
@@ -6011,7 +6011,7 @@ function fr_default() {
6011
6011
  localeError: error14()
6012
6012
  };
6013
6013
  }
6014
- // node_modules/zod/v4/locales/fr-CA.js
6014
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/fr-CA.js
6015
6015
  var error15 = () => {
6016
6016
  const Sizable = {
6017
6017
  string: { unit: "caract\xE8res", verb: "avoir" },
@@ -6118,7 +6118,7 @@ function fr_CA_default() {
6118
6118
  localeError: error15()
6119
6119
  };
6120
6120
  }
6121
- // node_modules/zod/v4/locales/he.js
6121
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/he.js
6122
6122
  var error16 = () => {
6123
6123
  const TypeNames = {
6124
6124
  string: { label: "\u05DE\u05D7\u05E8\u05D5\u05D6\u05EA", gender: "f" },
@@ -6311,7 +6311,7 @@ function he_default() {
6311
6311
  localeError: error16()
6312
6312
  };
6313
6313
  }
6314
- // node_modules/zod/v4/locales/hu.js
6314
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/hu.js
6315
6315
  var error17 = () => {
6316
6316
  const Sizable = {
6317
6317
  string: { unit: "karakter", verb: "legyen" },
@@ -6419,7 +6419,7 @@ function hu_default() {
6419
6419
  localeError: error17()
6420
6420
  };
6421
6421
  }
6422
- // node_modules/zod/v4/locales/hy.js
6422
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/hy.js
6423
6423
  function getArmenianPlural(count, one, many) {
6424
6424
  return Math.abs(count) === 1 ? one : many;
6425
6425
  }
@@ -6566,7 +6566,7 @@ function hy_default() {
6566
6566
  localeError: error18()
6567
6567
  };
6568
6568
  }
6569
- // node_modules/zod/v4/locales/id.js
6569
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/id.js
6570
6570
  var error19 = () => {
6571
6571
  const Sizable = {
6572
6572
  string: { unit: "karakter", verb: "memiliki" },
@@ -6672,7 +6672,7 @@ function id_default() {
6672
6672
  localeError: error19()
6673
6673
  };
6674
6674
  }
6675
- // node_modules/zod/v4/locales/is.js
6675
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/is.js
6676
6676
  var error20 = () => {
6677
6677
  const Sizable = {
6678
6678
  string: { unit: "stafi", verb: "a\xF0 hafa" },
@@ -6781,7 +6781,7 @@ function is_default() {
6781
6781
  localeError: error20()
6782
6782
  };
6783
6783
  }
6784
- // node_modules/zod/v4/locales/it.js
6784
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/it.js
6785
6785
  var error21 = () => {
6786
6786
  const Sizable = {
6787
6787
  string: { unit: "caratteri", verb: "avere" },
@@ -6889,7 +6889,7 @@ function it_default() {
6889
6889
  localeError: error21()
6890
6890
  };
6891
6891
  }
6892
- // node_modules/zod/v4/locales/ja.js
6892
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ja.js
6893
6893
  var error22 = () => {
6894
6894
  const Sizable = {
6895
6895
  string: { unit: "\u6587\u5B57", verb: "\u3067\u3042\u308B" },
@@ -6996,7 +6996,7 @@ function ja_default() {
6996
6996
  localeError: error22()
6997
6997
  };
6998
6998
  }
6999
- // node_modules/zod/v4/locales/ka.js
6999
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ka.js
7000
7000
  var error23 = () => {
7001
7001
  const Sizable = {
7002
7002
  string: { unit: "\u10E1\u10D8\u10DB\u10D1\u10DD\u10DA\u10DD", verb: "\u10E3\u10DC\u10D3\u10D0 \u10E8\u10D4\u10D8\u10EA\u10D0\u10D5\u10D3\u10D4\u10E1" },
@@ -7108,7 +7108,7 @@ function ka_default() {
7108
7108
  localeError: error23()
7109
7109
  };
7110
7110
  }
7111
- // node_modules/zod/v4/locales/km.js
7111
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/km.js
7112
7112
  var error24 = () => {
7113
7113
  const Sizable = {
7114
7114
  string: { unit: "\u178F\u17BD\u17A2\u1780\u17D2\u179F\u179A", verb: "\u1782\u17BD\u179A\u1798\u17B6\u1793" },
@@ -7219,11 +7219,11 @@ function km_default() {
7219
7219
  };
7220
7220
  }
7221
7221
 
7222
- // node_modules/zod/v4/locales/kh.js
7222
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/kh.js
7223
7223
  function kh_default() {
7224
7224
  return km_default();
7225
7225
  }
7226
- // node_modules/zod/v4/locales/ko.js
7226
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ko.js
7227
7227
  var error25 = () => {
7228
7228
  const Sizable = {
7229
7229
  string: { unit: "\uBB38\uC790", verb: "to have" },
@@ -7334,7 +7334,7 @@ function ko_default() {
7334
7334
  localeError: error25()
7335
7335
  };
7336
7336
  }
7337
- // node_modules/zod/v4/locales/lt.js
7337
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/lt.js
7338
7338
  var capitalizeFirstCharacter = (text) => {
7339
7339
  return text.charAt(0).toUpperCase() + text.slice(1);
7340
7340
  };
@@ -7537,7 +7537,7 @@ function lt_default() {
7537
7537
  localeError: error26()
7538
7538
  };
7539
7539
  }
7540
- // node_modules/zod/v4/locales/mk.js
7540
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/mk.js
7541
7541
  var error27 = () => {
7542
7542
  const Sizable = {
7543
7543
  string: { unit: "\u0437\u043D\u0430\u0446\u0438", verb: "\u0434\u0430 \u0438\u043C\u0430\u0430\u0442" },
@@ -7646,7 +7646,7 @@ function mk_default() {
7646
7646
  localeError: error27()
7647
7647
  };
7648
7648
  }
7649
- // node_modules/zod/v4/locales/ms.js
7649
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ms.js
7650
7650
  var error28 = () => {
7651
7651
  const Sizable = {
7652
7652
  string: { unit: "aksara", verb: "mempunyai" },
@@ -7753,7 +7753,7 @@ function ms_default() {
7753
7753
  localeError: error28()
7754
7754
  };
7755
7755
  }
7756
- // node_modules/zod/v4/locales/nl.js
7756
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/nl.js
7757
7757
  var error29 = () => {
7758
7758
  const Sizable = {
7759
7759
  string: { unit: "tekens", verb: "heeft" },
@@ -7863,7 +7863,7 @@ function nl_default() {
7863
7863
  localeError: error29()
7864
7864
  };
7865
7865
  }
7866
- // node_modules/zod/v4/locales/no.js
7866
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/no.js
7867
7867
  var error30 = () => {
7868
7868
  const Sizable = {
7869
7869
  string: { unit: "tegn", verb: "\xE5 ha" },
@@ -7971,7 +7971,7 @@ function no_default() {
7971
7971
  localeError: error30()
7972
7972
  };
7973
7973
  }
7974
- // node_modules/zod/v4/locales/ota.js
7974
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ota.js
7975
7975
  var error31 = () => {
7976
7976
  const Sizable = {
7977
7977
  string: { unit: "harf", verb: "olmal\u0131d\u0131r" },
@@ -8080,7 +8080,7 @@ function ota_default() {
8080
8080
  localeError: error31()
8081
8081
  };
8082
8082
  }
8083
- // node_modules/zod/v4/locales/ps.js
8083
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ps.js
8084
8084
  var error32 = () => {
8085
8085
  const Sizable = {
8086
8086
  string: { unit: "\u062A\u0648\u06A9\u064A", verb: "\u0648\u0644\u0631\u064A" },
@@ -8194,7 +8194,7 @@ function ps_default() {
8194
8194
  localeError: error32()
8195
8195
  };
8196
8196
  }
8197
- // node_modules/zod/v4/locales/pl.js
8197
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/pl.js
8198
8198
  var error33 = () => {
8199
8199
  const Sizable = {
8200
8200
  string: { unit: "znak\xF3w", verb: "mie\u0107" },
@@ -8303,7 +8303,7 @@ function pl_default() {
8303
8303
  localeError: error33()
8304
8304
  };
8305
8305
  }
8306
- // node_modules/zod/v4/locales/pt.js
8306
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/pt.js
8307
8307
  var error34 = () => {
8308
8308
  const Sizable = {
8309
8309
  string: { unit: "caracteres", verb: "ter" },
@@ -8411,7 +8411,7 @@ function pt_default() {
8411
8411
  localeError: error34()
8412
8412
  };
8413
8413
  }
8414
- // node_modules/zod/v4/locales/ru.js
8414
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ru.js
8415
8415
  function getRussianPlural(count, one, few, many) {
8416
8416
  const absCount = Math.abs(count);
8417
8417
  const lastDigit = absCount % 10;
@@ -8567,7 +8567,7 @@ function ru_default() {
8567
8567
  localeError: error35()
8568
8568
  };
8569
8569
  }
8570
- // node_modules/zod/v4/locales/sl.js
8570
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/sl.js
8571
8571
  var error36 = () => {
8572
8572
  const Sizable = {
8573
8573
  string: { unit: "znakov", verb: "imeti" },
@@ -8676,7 +8676,7 @@ function sl_default() {
8676
8676
  localeError: error36()
8677
8677
  };
8678
8678
  }
8679
- // node_modules/zod/v4/locales/sv.js
8679
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/sv.js
8680
8680
  var error37 = () => {
8681
8681
  const Sizable = {
8682
8682
  string: { unit: "tecken", verb: "att ha" },
@@ -8786,7 +8786,7 @@ function sv_default() {
8786
8786
  localeError: error37()
8787
8787
  };
8788
8788
  }
8789
- // node_modules/zod/v4/locales/ta.js
8789
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ta.js
8790
8790
  var error38 = () => {
8791
8791
  const Sizable = {
8792
8792
  string: { unit: "\u0B8E\u0BB4\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1\u0B95\u0BCD\u0B95\u0BB3\u0BCD", verb: "\u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BBF\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD" },
@@ -8896,7 +8896,7 @@ function ta_default() {
8896
8896
  localeError: error38()
8897
8897
  };
8898
8898
  }
8899
- // node_modules/zod/v4/locales/th.js
8899
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/th.js
8900
8900
  var error39 = () => {
8901
8901
  const Sizable = {
8902
8902
  string: { unit: "\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23", verb: "\u0E04\u0E27\u0E23\u0E21\u0E35" },
@@ -9006,7 +9006,7 @@ function th_default() {
9006
9006
  localeError: error39()
9007
9007
  };
9008
9008
  }
9009
- // node_modules/zod/v4/locales/tr.js
9009
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/tr.js
9010
9010
  var error40 = () => {
9011
9011
  const Sizable = {
9012
9012
  string: { unit: "karakter", verb: "olmal\u0131" },
@@ -9111,7 +9111,7 @@ function tr_default() {
9111
9111
  localeError: error40()
9112
9112
  };
9113
9113
  }
9114
- // node_modules/zod/v4/locales/uk.js
9114
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/uk.js
9115
9115
  var error41 = () => {
9116
9116
  const Sizable = {
9117
9117
  string: { unit: "\u0441\u0438\u043C\u0432\u043E\u043B\u0456\u0432", verb: "\u043C\u0430\u0442\u0438\u043C\u0435" },
@@ -9220,11 +9220,11 @@ function uk_default() {
9220
9220
  };
9221
9221
  }
9222
9222
 
9223
- // node_modules/zod/v4/locales/ua.js
9223
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ua.js
9224
9224
  function ua_default() {
9225
9225
  return uk_default();
9226
9226
  }
9227
- // node_modules/zod/v4/locales/ur.js
9227
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/ur.js
9228
9228
  var error42 = () => {
9229
9229
  const Sizable = {
9230
9230
  string: { unit: "\u062D\u0631\u0648\u0641", verb: "\u06C1\u0648\u0646\u0627" },
@@ -9334,7 +9334,7 @@ function ur_default() {
9334
9334
  localeError: error42()
9335
9335
  };
9336
9336
  }
9337
- // node_modules/zod/v4/locales/uz.js
9337
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/uz.js
9338
9338
  var error43 = () => {
9339
9339
  const Sizable = {
9340
9340
  string: { unit: "belgi", verb: "bo\u2018lishi kerak" },
@@ -9443,7 +9443,7 @@ function uz_default() {
9443
9443
  localeError: error43()
9444
9444
  };
9445
9445
  }
9446
- // node_modules/zod/v4/locales/vi.js
9446
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/vi.js
9447
9447
  var error44 = () => {
9448
9448
  const Sizable = {
9449
9449
  string: { unit: "k\xFD t\u1EF1", verb: "c\xF3" },
@@ -9551,7 +9551,7 @@ function vi_default() {
9551
9551
  localeError: error44()
9552
9552
  };
9553
9553
  }
9554
- // node_modules/zod/v4/locales/zh-CN.js
9554
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/zh-CN.js
9555
9555
  var error45 = () => {
9556
9556
  const Sizable = {
9557
9557
  string: { unit: "\u5B57\u7B26", verb: "\u5305\u542B" },
@@ -9660,7 +9660,7 @@ function zh_CN_default() {
9660
9660
  localeError: error45()
9661
9661
  };
9662
9662
  }
9663
- // node_modules/zod/v4/locales/zh-TW.js
9663
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/zh-TW.js
9664
9664
  var error46 = () => {
9665
9665
  const Sizable = {
9666
9666
  string: { unit: "\u5B57\u5143", verb: "\u64C1\u6709" },
@@ -9767,7 +9767,7 @@ function zh_TW_default() {
9767
9767
  localeError: error46()
9768
9768
  };
9769
9769
  }
9770
- // node_modules/zod/v4/locales/yo.js
9770
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/locales/yo.js
9771
9771
  var error47 = () => {
9772
9772
  const Sizable = {
9773
9773
  string: { unit: "\xE0mi", verb: "n\xED" },
@@ -9874,7 +9874,7 @@ function yo_default() {
9874
9874
  localeError: error47()
9875
9875
  };
9876
9876
  }
9877
- // node_modules/zod/v4/core/registries.js
9877
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/registries.js
9878
9878
  var _a;
9879
9879
  var $output = Symbol("ZodOutput");
9880
9880
  var $input = Symbol("ZodInput");
@@ -9924,7 +9924,7 @@ function registry() {
9924
9924
  }
9925
9925
  (_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
9926
9926
  var globalRegistry = globalThis.__zod_globalRegistry;
9927
- // node_modules/zod/v4/core/api.js
9927
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/api.js
9928
9928
  function _string(Class2, params) {
9929
9929
  return new Class2({
9930
9930
  type: "string",
@@ -10844,7 +10844,7 @@ function _stringFormat(Class2, format, fnOrRegex, _params = {}) {
10844
10844
  const inst = new Class2(def);
10845
10845
  return inst;
10846
10846
  }
10847
- // node_modules/zod/v4/core/to-json-schema.js
10847
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/to-json-schema.js
10848
10848
  function initializeContext(params) {
10849
10849
  let target = params?.target ?? "draft-2020-12";
10850
10850
  if (target === "draft-4")
@@ -11189,7 +11189,7 @@ var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) =
11189
11189
  extractDefs(ctx, schema);
11190
11190
  return finalize(ctx, schema);
11191
11191
  };
11192
- // node_modules/zod/v4/core/json-schema-processors.js
11192
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/json-schema-processors.js
11193
11193
  var formatMap = {
11194
11194
  guid: "uuid",
11195
11195
  url: "uri",
@@ -11734,7 +11734,7 @@ function toJSONSchema(input, params) {
11734
11734
  extractDefs(ctx, input);
11735
11735
  return finalize(ctx, input);
11736
11736
  }
11737
- // node_modules/zod/v4/core/json-schema-generator.js
11737
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/json-schema-generator.js
11738
11738
  class JSONSchemaGenerator {
11739
11739
  get metadataRegistry() {
11740
11740
  return this.ctx.metadataRegistry;
@@ -11793,9 +11793,9 @@ class JSONSchemaGenerator {
11793
11793
  return plainResult;
11794
11794
  }
11795
11795
  }
11796
- // node_modules/zod/v4/core/json-schema.js
11796
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/json-schema.js
11797
11797
  var exports_json_schema = {};
11798
- // node_modules/zod/v4/classic/schemas.js
11798
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/schemas.js
11799
11799
  var exports_schemas2 = {};
11800
11800
  __export(exports_schemas2, {
11801
11801
  xor: () => xor,
@@ -11964,7 +11964,7 @@ __export(exports_schemas2, {
11964
11964
  ZodAny: () => ZodAny
11965
11965
  });
11966
11966
 
11967
- // node_modules/zod/v4/classic/checks.js
11967
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/checks.js
11968
11968
  var exports_checks2 = {};
11969
11969
  __export(exports_checks2, {
11970
11970
  uppercase: () => _uppercase,
@@ -11998,7 +11998,7 @@ __export(exports_checks2, {
11998
11998
  endsWith: () => _endsWith
11999
11999
  });
12000
12000
 
12001
- // node_modules/zod/v4/classic/iso.js
12001
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/iso.js
12002
12002
  var exports_iso = {};
12003
12003
  __export(exports_iso, {
12004
12004
  time: () => time2,
@@ -12039,7 +12039,7 @@ function duration2(params) {
12039
12039
  return _isoDuration(ZodISODuration, params);
12040
12040
  }
12041
12041
 
12042
- // node_modules/zod/v4/classic/errors.js
12042
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/errors.js
12043
12043
  var initializer2 = (inst, issues) => {
12044
12044
  $ZodError.init(inst, issues);
12045
12045
  inst.name = "ZodError";
@@ -12074,7 +12074,7 @@ var ZodRealError = $constructor("ZodError", initializer2, {
12074
12074
  Parent: Error
12075
12075
  });
12076
12076
 
12077
- // node_modules/zod/v4/classic/parse.js
12077
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/parse.js
12078
12078
  var parse3 = /* @__PURE__ */ _parse(ZodRealError);
12079
12079
  var parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
12080
12080
  var safeParse2 = /* @__PURE__ */ _safeParse(ZodRealError);
@@ -12088,7 +12088,7 @@ var safeDecode2 = /* @__PURE__ */ _safeDecode(ZodRealError);
12088
12088
  var safeEncodeAsync2 = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
12089
12089
  var safeDecodeAsync2 = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
12090
12090
 
12091
- // node_modules/zod/v4/classic/schemas.js
12091
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/schemas.js
12092
12092
  var ZodType = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
12093
12093
  $ZodType.init(inst, def);
12094
12094
  Object.assign(inst["~standard"], {
@@ -13164,7 +13164,7 @@ function json(params) {
13164
13164
  function preprocess(fn, schema) {
13165
13165
  return pipe(transform(fn), schema);
13166
13166
  }
13167
- // node_modules/zod/v4/classic/compat.js
13167
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/compat.js
13168
13168
  var ZodIssueCode = {
13169
13169
  invalid_type: "invalid_type",
13170
13170
  too_big: "too_big",
@@ -13188,7 +13188,7 @@ function getErrorMap() {
13188
13188
  }
13189
13189
  var ZodFirstPartyTypeKind;
13190
13190
  (function(ZodFirstPartyTypeKind2) {})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
13191
- // node_modules/zod/v4/classic/from-json-schema.js
13191
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/from-json-schema.js
13192
13192
  var z = {
13193
13193
  ...exports_schemas2,
13194
13194
  ...exports_checks2,
@@ -13649,7 +13649,7 @@ function fromJSONSchema(schema, params) {
13649
13649
  };
13650
13650
  return convertSchema(schema, ctx);
13651
13651
  }
13652
- // node_modules/zod/v4/classic/coerce.js
13652
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/coerce.js
13653
13653
  var exports_coerce = {};
13654
13654
  __export(exports_coerce, {
13655
13655
  string: () => string3,
@@ -13674,7 +13674,7 @@ function date4(params) {
13674
13674
  return _coercedDate(ZodDate, params);
13675
13675
  }
13676
13676
 
13677
- // node_modules/zod/v4/classic/external.js
13677
+ // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
13678
13678
  config(en_default());
13679
13679
  // src/features/magic-context/defaults.ts
13680
13680
  var DEFAULT_PROTECTED_TAGS = 20;
@@ -13731,7 +13731,8 @@ var DreamerConfigSchema = AgentOverrideConfigSchema.merge(exports_external.objec
13731
13731
  schedule: exports_external.string().default("02:00-06:00"),
13732
13732
  max_runtime_minutes: exports_external.number().min(10).default(120),
13733
13733
  tasks: exports_external.array(DreamingTaskSchema).default(DEFAULT_DREAMER_TASKS),
13734
- task_timeout_minutes: exports_external.number().min(5).default(20)
13734
+ task_timeout_minutes: exports_external.number().min(5).default(20),
13735
+ inject_docs: exports_external.boolean().default(true)
13735
13736
  }));
13736
13737
  var SidekickConfigSchema = AgentOverrideConfigSchema.extend({
13737
13738
  enabled: exports_external.boolean().default(false),
@@ -13788,7 +13789,7 @@ var MagicContextConfigSchema = exports_external.object({
13788
13789
  exports_external.number().min(35).max(95),
13789
13790
  exports_external.object({ default: exports_external.number().min(35).max(95) }).catchall(exports_external.number().min(35).max(95))
13790
13791
  ]).default(DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE),
13791
- protected_tags: exports_external.number().min(1).max(20).optional(),
13792
+ protected_tags: exports_external.number().min(1).max(100).optional(),
13792
13793
  auto_drop_tool_age: exports_external.number().min(10).default(100),
13793
13794
  clear_reasoning_age: exports_external.number().min(10).default(50),
13794
13795
  iteration_nudge_threshold: exports_external.number().min(5).default(15),
@@ -15098,6 +15099,60 @@ function getErrorMessage(error48) {
15098
15099
  return error48 instanceof Error ? error48.message : String(error48);
15099
15100
  }
15100
15101
 
15102
+ // src/features/magic-context/storage-smart-notes.ts
15103
+ function isSmartNoteRow(row) {
15104
+ if (row === null || typeof row !== "object")
15105
+ return false;
15106
+ const r = row;
15107
+ return typeof r.id === "number" && typeof r.project_path === "string" && typeof r.content === "string" && typeof r.surface_condition === "string" && typeof r.status === "string" && typeof r.created_at === "number" && typeof r.updated_at === "number";
15108
+ }
15109
+ function toSmartNote(row) {
15110
+ return {
15111
+ id: row.id,
15112
+ projectPath: row.project_path,
15113
+ content: row.content,
15114
+ surfaceCondition: row.surface_condition,
15115
+ status: row.status,
15116
+ createdSessionId: row.created_session_id && row.created_session_id.length > 0 ? row.created_session_id : null,
15117
+ createdAt: row.created_at,
15118
+ updatedAt: row.updated_at,
15119
+ lastCheckedAt: row.last_checked_at,
15120
+ readyAt: row.ready_at,
15121
+ readyReason: row.ready_reason && row.ready_reason.length > 0 ? row.ready_reason : null
15122
+ };
15123
+ }
15124
+ function addSmartNote(db, projectPath, content, surfaceCondition, sessionId) {
15125
+ const now = Date.now();
15126
+ const result = db.prepare("INSERT INTO smart_notes (project_path, content, surface_condition, status, created_session_id, created_at, updated_at) VALUES (?, ?, ?, 'pending', ?, ?, ?) RETURNING *").get(projectPath, content, surfaceCondition, sessionId ?? null, now, now);
15127
+ if (!isSmartNoteRow(result)) {
15128
+ throw new Error("[smart-notes] failed to insert smart note");
15129
+ }
15130
+ return toSmartNote(result);
15131
+ }
15132
+ function getSmartNotes(db, projectPath, status) {
15133
+ const query = status ? "SELECT * FROM smart_notes WHERE project_path = ? AND status = ? ORDER BY created_at ASC" : "SELECT * FROM smart_notes WHERE project_path = ? AND status != 'dismissed' ORDER BY created_at ASC";
15134
+ const params = status ? [projectPath, status] : [projectPath];
15135
+ return db.prepare(query).all(...params).filter(isSmartNoteRow).map(toSmartNote);
15136
+ }
15137
+ function getPendingSmartNotes(db, projectPath) {
15138
+ return getSmartNotes(db, projectPath, "pending");
15139
+ }
15140
+ function getReadySmartNotes(db, projectPath) {
15141
+ return getSmartNotes(db, projectPath, "ready");
15142
+ }
15143
+ function markSmartNoteReady(db, noteId, readyReason) {
15144
+ const now = Date.now();
15145
+ db.prepare("UPDATE smart_notes SET status = 'ready', ready_at = ?, ready_reason = ?, updated_at = ?, last_checked_at = ? WHERE id = ?").run(now, readyReason ?? null, now, now, noteId);
15146
+ }
15147
+ function markSmartNoteChecked(db, noteId) {
15148
+ const now = Date.now();
15149
+ db.prepare("UPDATE smart_notes SET last_checked_at = ?, updated_at = ? WHERE id = ?").run(now, now, noteId);
15150
+ }
15151
+ function dismissSmartNote(db, noteId) {
15152
+ const result = db.prepare("UPDATE smart_notes SET status = 'dismissed', updated_at = ? WHERE id = ?").run(Date.now(), noteId);
15153
+ return result.changes > 0;
15154
+ }
15155
+
15101
15156
  // src/features/magic-context/dreamer/runner.ts
15102
15157
  var dreamProjectDirectories = new Map;
15103
15158
  function registerDreamProjectDirectory(projectIdentity, directory) {
@@ -15247,6 +15302,22 @@ async function runDream(args) {
15247
15302
  }
15248
15303
  }
15249
15304
  }
15305
+ if (Date.now() <= deadline) {
15306
+ try {
15307
+ await evaluateSmartNotes({
15308
+ db: args.db,
15309
+ client: args.client,
15310
+ projectIdentity: args.projectIdentity,
15311
+ parentSessionId,
15312
+ sessionDirectory: args.sessionDirectory,
15313
+ holderId,
15314
+ deadline,
15315
+ result
15316
+ });
15317
+ } catch (error48) {
15318
+ log(`[dreamer] smart note evaluation failed: ${getErrorMessage(error48)}`);
15319
+ }
15320
+ }
15250
15321
  } finally {
15251
15322
  releaseLease(args.db, holderId);
15252
15323
  log(`[dreamer] lease released: ${holderId}`);
@@ -15263,6 +15334,141 @@ async function runDream(args) {
15263
15334
  log(`[dreamer] dream run finished in ${totalDuration}s: ${succeeded} succeeded, ${failed} failed`);
15264
15335
  return result;
15265
15336
  }
15337
+ async function evaluateSmartNotes(args) {
15338
+ const pendingNotes = getPendingSmartNotes(args.db, args.projectIdentity);
15339
+ if (pendingNotes.length === 0) {
15340
+ log("[dreamer] smart notes: no pending notes to evaluate");
15341
+ return;
15342
+ }
15343
+ log(`[dreamer] smart notes: evaluating ${pendingNotes.length} pending note(s)`);
15344
+ const noteDescriptions = pendingNotes.map((n) => `- Note #${n.id}: "${n.content}"
15345
+ Condition: ${n.surfaceCondition}`).join(`
15346
+ `);
15347
+ const evaluationPrompt = `You are evaluating smart note conditions for the magic-context system.
15348
+
15349
+ For each note below, determine whether its surface condition has been met.
15350
+ You have access to tools like GitHub CLI (gh), web search, and the local codebase to verify conditions.
15351
+
15352
+ ## Pending Smart Notes
15353
+
15354
+ ${noteDescriptions}
15355
+
15356
+ ## Instructions
15357
+
15358
+ 1. Check each condition using the tools available to you.
15359
+ 2. Be conservative \u2014 only mark a condition as met when you have clear evidence.
15360
+ 3. Respond with a JSON array of results:
15361
+
15362
+ \`\`\`json
15363
+ [
15364
+ { "id": <note_id>, "met": true/false, "reason": "brief explanation" }
15365
+ ]
15366
+ \`\`\`
15367
+
15368
+ Only include notes whose conditions you could definitively evaluate. Skip notes where you cannot determine the status (they will be re-evaluated next run).`;
15369
+ const taskStartedAt = Date.now();
15370
+ let agentSessionId = null;
15371
+ const abortController = new AbortController;
15372
+ const leaseInterval = setInterval(() => {
15373
+ try {
15374
+ if (!renewLease(args.db, args.holderId)) {
15375
+ log("[dreamer] smart notes: lease renewal failed \u2014 aborting");
15376
+ abortController.abort();
15377
+ }
15378
+ } catch {
15379
+ abortController.abort();
15380
+ }
15381
+ }, 60000);
15382
+ try {
15383
+ const createResponse = await args.client.session.create({
15384
+ body: {
15385
+ ...args.parentSessionId ? { parentID: args.parentSessionId } : {},
15386
+ title: "magic-context-dream-smart-notes"
15387
+ },
15388
+ query: { directory: args.sessionDirectory ?? args.projectIdentity }
15389
+ });
15390
+ const created = normalizeSDKResponse(createResponse, null, { preferResponseOnMissingData: true });
15391
+ agentSessionId = typeof created?.id === "string" ? created.id : null;
15392
+ if (!agentSessionId)
15393
+ throw new Error("Could not create smart note evaluation session.");
15394
+ log(`[dreamer] smart notes: child session created ${agentSessionId}`);
15395
+ const remainingMs = Math.max(0, args.deadline - Date.now());
15396
+ await promptSyncWithModelSuggestionRetry(args.client, {
15397
+ path: { id: agentSessionId },
15398
+ query: { directory: args.sessionDirectory ?? args.projectIdentity },
15399
+ body: {
15400
+ agent: DREAMER_AGENT,
15401
+ system: DREAMER_SYSTEM_PROMPT,
15402
+ parts: [{ type: "text", text: evaluationPrompt }]
15403
+ }
15404
+ }, { timeoutMs: Math.min(remainingMs, 5 * 60 * 1000), signal: abortController.signal });
15405
+ const messagesResponse = await args.client.session.messages({
15406
+ path: { id: agentSessionId },
15407
+ query: { directory: args.sessionDirectory ?? args.projectIdentity }
15408
+ });
15409
+ const messages = normalizeSDKResponse(messagesResponse, [], {
15410
+ preferResponseOnMissingData: true
15411
+ });
15412
+ const output = extractLatestAssistantText(messages);
15413
+ if (!output)
15414
+ throw new Error("Smart note evaluation returned no output.");
15415
+ const jsonMatch = output.match(/\[[\s\S]*?\]/);
15416
+ if (!jsonMatch) {
15417
+ log("[dreamer] smart notes: no JSON array found in output, skipping");
15418
+ for (const note of pendingNotes)
15419
+ markSmartNoteChecked(args.db, note.id);
15420
+ return;
15421
+ }
15422
+ const evaluations = JSON.parse(jsonMatch[0]);
15423
+ let surfaced = 0;
15424
+ let checked = 0;
15425
+ for (const evaluation of evaluations) {
15426
+ if (typeof evaluation.id !== "number")
15427
+ continue;
15428
+ const note = pendingNotes.find((n) => n.id === evaluation.id);
15429
+ if (!note)
15430
+ continue;
15431
+ if (evaluation.met) {
15432
+ markSmartNoteReady(args.db, note.id, evaluation.reason);
15433
+ surfaced++;
15434
+ log(`[dreamer] smart notes: #${note.id} condition MET \u2014 "${evaluation.reason ?? "condition satisfied"}"`);
15435
+ } else {
15436
+ markSmartNoteChecked(args.db, note.id);
15437
+ checked++;
15438
+ }
15439
+ }
15440
+ for (const note of pendingNotes) {
15441
+ if (!evaluations.some((e) => e.id === note.id)) {
15442
+ markSmartNoteChecked(args.db, note.id);
15443
+ }
15444
+ }
15445
+ const durationMs = Date.now() - taskStartedAt;
15446
+ log(`[dreamer] smart notes: evaluated ${pendingNotes.length} notes in ${(durationMs / 1000).toFixed(1)}s \u2014 ${surfaced} surfaced, ${checked} still pending`);
15447
+ args.result.tasks.push({
15448
+ name: "smart-notes",
15449
+ durationMs,
15450
+ result: `${surfaced} surfaced, ${checked} still pending`
15451
+ });
15452
+ } catch (error48) {
15453
+ const durationMs = Date.now() - taskStartedAt;
15454
+ const errorMsg = getErrorMessage(error48);
15455
+ log(`[dreamer] smart notes: failed after ${(durationMs / 1000).toFixed(1)}s \u2014 ${errorMsg}`);
15456
+ args.result.tasks.push({
15457
+ name: "smart-notes",
15458
+ durationMs,
15459
+ result: null,
15460
+ error: errorMsg
15461
+ });
15462
+ } finally {
15463
+ clearInterval(leaseInterval);
15464
+ if (agentSessionId) {
15465
+ await args.client.session.delete({
15466
+ path: { id: agentSessionId },
15467
+ query: { directory: args.sessionDirectory ?? args.projectIdentity }
15468
+ }).catch(() => {});
15469
+ }
15470
+ }
15471
+ }
15266
15472
  var MAX_LEASE_RETRIES = 3;
15267
15473
  async function processDreamQueue(args) {
15268
15474
  const maxRuntimeMs = args.maxRuntimeMinutes * 60 * 1000;
@@ -15496,6 +15702,21 @@ function initializeDatabase(db) {
15496
15702
  CREATE INDEX IF NOT EXISTS idx_dream_queue_project ON dream_queue(project_path);
15497
15703
  CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, enqueued_at);
15498
15704
 
15705
+ CREATE TABLE IF NOT EXISTS smart_notes (
15706
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
15707
+ project_path TEXT NOT NULL,
15708
+ content TEXT NOT NULL,
15709
+ surface_condition TEXT NOT NULL,
15710
+ status TEXT NOT NULL DEFAULT 'pending',
15711
+ created_session_id TEXT,
15712
+ created_at INTEGER NOT NULL,
15713
+ updated_at INTEGER NOT NULL,
15714
+ last_checked_at INTEGER,
15715
+ ready_at INTEGER,
15716
+ ready_reason TEXT
15717
+ );
15718
+ CREATE INDEX IF NOT EXISTS idx_smart_notes_project_status ON smart_notes(project_path, status);
15719
+
15499
15720
  CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
15500
15721
  content,
15501
15722
  category,
@@ -15610,6 +15831,8 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
15610
15831
  ensureColumn(db, "session_meta", "times_execute_threshold_reached", "INTEGER DEFAULT 0");
15611
15832
  ensureColumn(db, "session_meta", "compartment_in_progress", "INTEGER DEFAULT 0");
15612
15833
  ensureColumn(db, "session_meta", "system_prompt_hash", "TEXT DEFAULT ''");
15834
+ ensureColumn(db, "session_meta", "cleared_reasoning_through_tag", "INTEGER DEFAULT 0");
15835
+ ensureColumn(db, "session_meta", "stripped_placeholder_ids", "TEXT DEFAULT ''");
15613
15836
  ensureColumn(db, "compartments", "start_message_id", "TEXT DEFAULT ''");
15614
15837
  ensureColumn(db, "compartments", "end_message_id", "TEXT DEFAULT ''");
15615
15838
  ensureColumn(db, "memory_embeddings", "model_id", "TEXT");
@@ -15690,14 +15913,15 @@ var META_COLUMNS = {
15690
15913
  lastInputTokens: "last_input_tokens",
15691
15914
  timesExecuteThresholdReached: "times_execute_threshold_reached",
15692
15915
  compartmentInProgress: "compartment_in_progress",
15693
- systemPromptHash: "system_prompt_hash"
15916
+ systemPromptHash: "system_prompt_hash",
15917
+ clearedReasoningThroughTag: "cleared_reasoning_through_tag"
15694
15918
  };
15695
15919
  var BOOLEAN_META_KEYS = new Set(["isSubagent", "compartmentInProgress"]);
15696
15920
  function isSessionMetaRow(row) {
15697
15921
  if (row === null || typeof row !== "object")
15698
15922
  return false;
15699
15923
  const r = row;
15700
- return typeof r.session_id === "string" && typeof r.last_response_time === "number" && typeof r.cache_ttl === "string" && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && typeof r.last_nudge_band === "string" && typeof r.last_transform_error === "string" && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && typeof r.times_execute_threshold_reached === "number" && typeof r.compartment_in_progress === "number" && (typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number");
15924
+ return typeof r.session_id === "string" && typeof r.last_response_time === "number" && typeof r.cache_ttl === "string" && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && typeof r.last_nudge_band === "string" && typeof r.last_transform_error === "string" && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && typeof r.times_execute_threshold_reached === "number" && typeof r.compartment_in_progress === "number" && (typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && typeof r.cleared_reasoning_through_tag === "number";
15701
15925
  }
15702
15926
  function getDefaultSessionMeta(sessionId) {
15703
15927
  return {
@@ -15713,12 +15937,13 @@ function getDefaultSessionMeta(sessionId) {
15713
15937
  lastInputTokens: 0,
15714
15938
  timesExecuteThresholdReached: 0,
15715
15939
  compartmentInProgress: false,
15716
- systemPromptHash: ""
15940
+ systemPromptHash: "",
15941
+ clearedReasoningThroughTag: 0
15717
15942
  };
15718
15943
  }
15719
15944
  function ensureSessionMetaRow(db, sessionId) {
15720
15945
  const defaults = getDefaultSessionMeta(sessionId);
15721
- db.prepare("INSERT OR IGNORE INTO session_meta (session_id, last_response_time, cache_ttl, counter, last_nudge_tokens, last_nudge_band, last_transform_error, is_subagent, last_context_percentage, last_input_tokens, times_execute_threshold_reached, compartment_in_progress, system_prompt_hash) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").run(sessionId, defaults.lastResponseTime, defaults.cacheTtl, defaults.counter, defaults.lastNudgeTokens, defaults.lastNudgeBand ?? "", defaults.lastTransformError ?? "", defaults.isSubagent ? 1 : 0, defaults.lastContextPercentage, defaults.lastInputTokens, defaults.timesExecuteThresholdReached, defaults.compartmentInProgress ? 1 : 0, defaults.systemPromptHash ?? "");
15946
+ db.prepare("INSERT OR IGNORE INTO session_meta (session_id, last_response_time, cache_ttl, counter, last_nudge_tokens, last_nudge_band, last_transform_error, is_subagent, last_context_percentage, last_input_tokens, times_execute_threshold_reached, compartment_in_progress, system_prompt_hash, cleared_reasoning_through_tag) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").run(sessionId, defaults.lastResponseTime, defaults.cacheTtl, defaults.counter, defaults.lastNudgeTokens, defaults.lastNudgeBand ?? "", defaults.lastTransformError ?? "", defaults.isSubagent ? 1 : 0, defaults.lastContextPercentage, defaults.lastInputTokens, defaults.timesExecuteThresholdReached, defaults.compartmentInProgress ? 1 : 0, defaults.systemPromptHash ?? "", defaults.clearedReasoningThroughTag);
15722
15947
  }
15723
15948
  function toSessionMeta(row) {
15724
15949
  return {
@@ -15734,7 +15959,8 @@ function toSessionMeta(row) {
15734
15959
  lastInputTokens: row.last_input_tokens,
15735
15960
  timesExecuteThresholdReached: row.times_execute_threshold_reached,
15736
15961
  compartmentInProgress: row.compartment_in_progress === 1,
15737
- systemPromptHash: String(row.system_prompt_hash)
15962
+ systemPromptHash: String(row.system_prompt_hash),
15963
+ clearedReasoningThroughTag: row.cleared_reasoning_through_tag
15738
15964
  };
15739
15965
  }
15740
15966
 
@@ -15861,6 +16087,23 @@ function setPersistedDeliveredNoteNudge(db, sessionId, text, messageId = "") {
15861
16087
  function clearPersistedNoteNudge(db, sessionId) {
15862
16088
  db.prepare("UPDATE session_meta SET note_nudge_trigger_pending = 0, note_nudge_trigger_message_id = '', note_nudge_sticky_text = '', note_nudge_sticky_message_id = '' WHERE session_id = ?").run(sessionId);
15863
16089
  }
16090
+ function getStrippedPlaceholderIds(db, sessionId) {
16091
+ const row = db.prepare("SELECT stripped_placeholder_ids FROM session_meta WHERE session_id = ?").get(sessionId);
16092
+ const raw = row?.stripped_placeholder_ids;
16093
+ if (!raw || raw.length === 0)
16094
+ return new Set;
16095
+ try {
16096
+ const parsed = JSON.parse(raw);
16097
+ if (Array.isArray(parsed))
16098
+ return new Set(parsed.filter((v) => typeof v === "string"));
16099
+ } catch {}
16100
+ return new Set;
16101
+ }
16102
+ function setStrippedPlaceholderIds(db, sessionId, ids) {
16103
+ ensureSessionMetaRow(db, sessionId);
16104
+ const json2 = ids.size > 0 ? JSON.stringify([...ids]) : "";
16105
+ db.prepare("UPDATE session_meta SET stripped_placeholder_ids = ? WHERE session_id = ?").run(json2, sessionId);
16106
+ }
15864
16107
  // src/shared/internal-initiator-marker.ts
15865
16108
  var OMO_INTERNAL_INITIATOR_MARKER = "<!-- OMO_INTERNAL_INITIATOR -->";
15866
16109
 
@@ -16349,7 +16592,7 @@ function ensureMessagesIndexed(db, sessionId, readMessages) {
16349
16592
 
16350
16593
  // src/features/magic-context/storage-meta-session.ts
16351
16594
  function getOrCreateSessionMeta(db, sessionId) {
16352
- const result = db.prepare("SELECT session_id, last_response_time, cache_ttl, counter, last_nudge_tokens, last_nudge_band, last_transform_error, is_subagent, last_context_percentage, last_input_tokens, times_execute_threshold_reached, compartment_in_progress, system_prompt_hash FROM session_meta WHERE session_id = ?").get(sessionId);
16595
+ const result = db.prepare("SELECT session_id, last_response_time, cache_ttl, counter, last_nudge_tokens, last_nudge_band, last_transform_error, is_subagent, last_context_percentage, last_input_tokens, times_execute_threshold_reached, compartment_in_progress, system_prompt_hash, cleared_reasoning_through_tag FROM session_meta WHERE session_id = ?").get(sessionId);
16353
16596
  if (isSessionMetaRow(result)) {
16354
16597
  return toSessionMeta(result);
16355
16598
  }
@@ -18380,11 +18623,19 @@ function createTextCompleteHandler() {
18380
18623
  }
18381
18624
 
18382
18625
  // src/hooks/magic-context/note-nudger.ts
18626
+ var NOTE_NUDGE_COOLDOWN_MS = 15 * 60 * 1000;
18627
+ var lastDeliveredAt = new Map;
18628
+ function getPersistedNoteNudgeDeliveredAt(_db, sessionId) {
18629
+ return lastDeliveredAt.get(sessionId) ?? 0;
18630
+ }
18631
+ function recordNoteNudgeDeliveryTime(sessionId) {
18632
+ lastDeliveredAt.set(sessionId, Date.now());
18633
+ }
18383
18634
  function onNoteTrigger(db, sessionId, trigger) {
18384
18635
  setPersistedNoteNudgeTrigger(db, sessionId);
18385
18636
  sessionLog(sessionId, `note-nudge: trigger fired (${trigger}), triggerPending=true`);
18386
18637
  }
18387
- function peekNoteNudgeText(db, sessionId, currentUserMessageId) {
18638
+ function peekNoteNudgeText(db, sessionId, currentUserMessageId, projectIdentity) {
18388
18639
  const state = getPersistedNoteNudge(db, sessionId);
18389
18640
  if (!state.triggerPending)
18390
18641
  return null;
@@ -18396,17 +18647,35 @@ function peekNoteNudgeText(db, sessionId, currentUserMessageId) {
18396
18647
  sessionLog(sessionId, `note-nudge: deferring \u2014 current user message ${currentUserMessageId} is same as trigger-time message`);
18397
18648
  return null;
18398
18649
  }
18650
+ if (state.stickyText && state.stickyMessageId) {
18651
+ const deliveredAt = getPersistedNoteNudgeDeliveredAt(db, sessionId);
18652
+ if (deliveredAt > 0 && Date.now() - deliveredAt < NOTE_NUDGE_COOLDOWN_MS) {
18653
+ sessionLog(sessionId, `note-nudge: suppressing \u2014 last delivered ${Math.round((Date.now() - deliveredAt) / 1000)}s ago (cooldown ${NOTE_NUDGE_COOLDOWN_MS / 60000}m)`);
18654
+ clearPersistedNoteNudge(db, sessionId);
18655
+ return null;
18656
+ }
18657
+ }
18399
18658
  const notes = getSessionNotes(db, sessionId);
18400
- if (notes.length === 0) {
18659
+ const readySmartCount = projectIdentity ? getReadySmartNotes(db, projectIdentity).length : 0;
18660
+ const totalCount = notes.length + readySmartCount;
18661
+ if (totalCount === 0) {
18401
18662
  sessionLog(sessionId, "note-nudge: triggerPending but no notes found, skipping");
18663
+ clearPersistedNoteNudge(db, sessionId);
18402
18664
  return null;
18403
18665
  }
18404
- sessionLog(sessionId, `note-nudge: delivering nudge for ${notes.length} notes`);
18405
- const plural = notes.length === 1 ? "note" : "notes";
18406
- return `You have ${notes.length} deferred ${plural}. Review with ctx_note read \u2014 some may be actionable now.`;
18666
+ const parts = [];
18667
+ if (notes.length > 0) {
18668
+ parts.push(`${notes.length} deferred note${notes.length === 1 ? "" : "s"}`);
18669
+ }
18670
+ if (readySmartCount > 0) {
18671
+ parts.push(`${readySmartCount} ready smart note${readySmartCount === 1 ? "" : "s"}`);
18672
+ }
18673
+ sessionLog(sessionId, `note-nudge: delivering nudge for ${parts.join(" and ")}`);
18674
+ return `You have ${parts.join(" and ")}. Review with ctx_note read \u2014 some may be actionable now.`;
18407
18675
  }
18408
18676
  function markNoteNudgeDelivered(db, sessionId, text, messageId) {
18409
18677
  setPersistedDeliveredNoteNudge(db, sessionId, messageId ? text : "", messageId ?? "");
18678
+ recordNoteNudgeDeliveryTime(sessionId);
18410
18679
  sessionLog(sessionId, messageId ? `note-nudge: marked delivered, sticky anchor=${messageId}` : "note-nudge: marked delivered without anchor");
18411
18680
  }
18412
18681
  function getStickyNoteNudge(db, sessionId) {
@@ -18540,6 +18809,52 @@ function stripDroppedPlaceholderMessages(messages) {
18540
18809
  }
18541
18810
  return stripped;
18542
18811
  }
18812
+ function replayClearedReasoning(messages, reasoningByMessage, messageTagNumbers, persistedWatermark) {
18813
+ if (persistedWatermark <= 0)
18814
+ return 0;
18815
+ let cleared = 0;
18816
+ for (const message of messages) {
18817
+ const msgTag = messageTagNumbers.get(message) ?? 0;
18818
+ if (msgTag === 0 || msgTag > persistedWatermark)
18819
+ continue;
18820
+ const parts = reasoningByMessage.get(message);
18821
+ if (!parts)
18822
+ continue;
18823
+ for (const tp of parts) {
18824
+ if (tp.thinking !== undefined && tp.thinking !== "[cleared]") {
18825
+ tp.thinking = "[cleared]";
18826
+ cleared++;
18827
+ }
18828
+ if (tp.text !== undefined && tp.text !== "[cleared]") {
18829
+ tp.text = "[cleared]";
18830
+ cleared++;
18831
+ }
18832
+ }
18833
+ }
18834
+ return cleared;
18835
+ }
18836
+ function replayStrippedInlineThinking(messages, messageTagNumbers, persistedWatermark) {
18837
+ if (persistedWatermark <= 0)
18838
+ return 0;
18839
+ let stripped = 0;
18840
+ for (const message of messages) {
18841
+ if (message.info.role !== "assistant")
18842
+ continue;
18843
+ const msgTag = messageTagNumbers.get(message) ?? 0;
18844
+ if (msgTag === 0 || msgTag > persistedWatermark)
18845
+ continue;
18846
+ for (const part of message.parts) {
18847
+ if (!isRecord(part) || part.type !== "text" || typeof part.text !== "string")
18848
+ continue;
18849
+ const cleaned = part.text.replace(INLINE_THINKING_PATTERN, "");
18850
+ if (cleaned !== part.text) {
18851
+ part.text = cleaned;
18852
+ stripped++;
18853
+ }
18854
+ }
18855
+ }
18856
+ return stripped;
18857
+ }
18543
18858
  function clearOldReasoning(messages, reasoningByMessage, messageTagNumbers, clearReasoningAge) {
18544
18859
  const maxTag = findMaxTag(messageTagNumbers);
18545
18860
  if (maxTag === 0)
@@ -21169,7 +21484,21 @@ function runPostTransformPhase(args) {
21169
21484
  stripClearedReasoning(args.messages);
21170
21485
  const strippedInline = stripInlineThinking(args.messages, args.messageTagNumbers, args.clearReasoningAge);
21171
21486
  if (clearedReasoning > 0 || strippedInline > 0) {
21172
- sessionLog(args.sessionId, `reasoning cleanup: cleared=${clearedReasoning} inlineStripped=${strippedInline}`);
21487
+ let maxTag = 0;
21488
+ for (const tag of args.messageTagNumbers.values()) {
21489
+ if (tag > maxTag)
21490
+ maxTag = tag;
21491
+ }
21492
+ const newWatermark = maxTag - args.clearReasoningAge;
21493
+ const currentWatermark = args.sessionMeta?.clearedReasoningThroughTag ?? 0;
21494
+ if (newWatermark > currentWatermark) {
21495
+ updateSessionMeta(args.db, args.sessionId, {
21496
+ clearedReasoningThroughTag: newWatermark
21497
+ });
21498
+ sessionLog(args.sessionId, `reasoning cleanup: cleared=${clearedReasoning} inlineStripped=${strippedInline} watermark=${currentWatermark}\u2192${newWatermark}`);
21499
+ } else {
21500
+ sessionLog(args.sessionId, `reasoning cleanup: cleared=${clearedReasoning} inlineStripped=${strippedInline} watermark=${currentWatermark} (unchanged)`);
21501
+ }
21173
21502
  }
21174
21503
  logTransformTiming(args.sessionId, "clearOldReasoning", t7);
21175
21504
  args.flushedSessions.delete(args.sessionId);
@@ -21209,9 +21538,50 @@ function runPostTransformPhase(args) {
21209
21538
  sessionLog(args.sessionId, `transform: injected ${compartmentResult.compartmentCount} compartments ` + `(covering raw messages 1-${compartmentResult.compartmentEndMessage}, ` + `skipped ${compartmentResult.skippedVisibleMessages} visible messages)`);
21210
21539
  }
21211
21540
  }
21212
- const strippedDropped = stripDroppedPlaceholderMessages(args.messages);
21213
- if (strippedDropped > 0) {
21214
- sessionLog(args.sessionId, `stripped ${strippedDropped} empty dropped-placeholder messages`);
21541
+ {
21542
+ const persistedIds = getStrippedPlaceholderIds(args.db, args.sessionId);
21543
+ if (persistedIds.size > 0) {
21544
+ let replayed = 0;
21545
+ for (let i = args.messages.length - 1;i >= 0; i--) {
21546
+ const msgId = args.messages[i].info.id;
21547
+ if (msgId && persistedIds.has(msgId)) {
21548
+ args.messages.splice(i, 1);
21549
+ replayed++;
21550
+ }
21551
+ }
21552
+ if (replayed > 0) {
21553
+ sessionLog(args.sessionId, `placeholder replay: removed ${replayed} previously-stripped messages`);
21554
+ }
21555
+ }
21556
+ if (isCacheBustingPass) {
21557
+ const preStripIds = new Set;
21558
+ for (const msg of args.messages) {
21559
+ if (msg.info.id)
21560
+ preStripIds.add(msg.info.id);
21561
+ }
21562
+ const strippedDropped = stripDroppedPlaceholderMessages(args.messages);
21563
+ if (strippedDropped > 0) {
21564
+ const postStripIds = new Set;
21565
+ for (const msg of args.messages) {
21566
+ if (msg.info.id)
21567
+ postStripIds.add(msg.info.id);
21568
+ }
21569
+ let newlyStrippedCount = 0;
21570
+ for (const id of preStripIds) {
21571
+ if (!postStripIds.has(id)) {
21572
+ persistedIds.add(id);
21573
+ newlyStrippedCount++;
21574
+ }
21575
+ }
21576
+ for (const id of persistedIds) {
21577
+ if (!preStripIds.has(id) && !postStripIds.has(id)) {
21578
+ persistedIds.delete(id);
21579
+ }
21580
+ }
21581
+ setStrippedPlaceholderIds(args.db, args.sessionId, persistedIds);
21582
+ sessionLog(args.sessionId, `stripped ${strippedDropped} placeholder messages (${newlyStrippedCount} new, ${persistedIds.size} total persisted)`);
21583
+ }
21584
+ }
21215
21585
  }
21216
21586
  if (isCacheBustingPass) {
21217
21587
  const protectedTailStart = Math.max(0, args.messages.length - args.protectedTags * 2);
@@ -21392,6 +21762,16 @@ function createTransform(deps) {
21392
21762
  const t3 = performance.now();
21393
21763
  const strippedStructuralNoise = stripStructuralNoise(messages);
21394
21764
  logTransformTiming(sessionId, "stripStructuralNoise", t3, `strippedParts=${strippedStructuralNoise}`);
21765
+ const persistedReasoningWatermark = sessionMeta?.clearedReasoningThroughTag ?? 0;
21766
+ if (persistedReasoningWatermark > 0) {
21767
+ const tReplay = performance.now();
21768
+ const replayed = replayClearedReasoning(messages, reasoningByMessage, messageTagNumbers, persistedReasoningWatermark);
21769
+ const replayedInline = replayStrippedInlineThinking(messages, messageTagNumbers, persistedReasoningWatermark);
21770
+ if (replayed > 0 || replayedInline > 0) {
21771
+ sessionLog(sessionId, `reasoning replay: cleared=${replayed} inlineStripped=${replayedInline} (watermark=${persistedReasoningWatermark})`);
21772
+ }
21773
+ logTransformTiming(sessionId, "replayReasoningClearing", tReplay);
21774
+ }
21395
21775
  const t4 = performance.now();
21396
21776
  const strippedClearedReasoning = stripClearedReasoning(messages);
21397
21777
  logTransformTiming(sessionId, "stripClearedReasoning", t4, `strippedParts=${strippedClearedReasoning}`);
@@ -21592,7 +21972,11 @@ function createToolExecuteAfterHook(args) {
21592
21972
  args.recentReduceBySession.set(typedInput.sessionID, Date.now());
21593
21973
  }
21594
21974
  if (typedInput.tool === "todowrite") {
21595
- onNoteTrigger(args.db, typedInput.sessionID, "todos_complete");
21975
+ const todoArgs = typedInput.args;
21976
+ const todos = todoArgs?.todos;
21977
+ if (Array.isArray(todos) && todos.length > 0 && todos.every((t) => t.status === "completed" || t.status === "cancelled")) {
21978
+ onNoteTrigger(args.db, typedInput.sessionID, "todos_complete");
21979
+ }
21596
21980
  }
21597
21981
  if (typedInput.tool === "ctx_note") {
21598
21982
  clearNoteNudgeState(args.db, typedInput.sessionID);
@@ -21601,6 +21985,10 @@ function createToolExecuteAfterHook(args) {
21601
21985
  };
21602
21986
  }
21603
21987
 
21988
+ // src/hooks/magic-context/system-prompt-hash.ts
21989
+ import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
21990
+ import { join as join8 } from "path";
21991
+
21604
21992
  // src/agents/magic-context-prompt.ts
21605
21993
  var BASE_INTRO = (protectedTags) => `Messages and tool outputs are tagged with \xA7N\xA7 identifiers (e.g., \xA71\xA7, \xA742\xA7).
21606
21994
  Use \`ctx_reduce\` to manage context size. It supports one operation:
@@ -21755,16 +22143,20 @@ function detectAgentFromSystemPrompt(systemPrompt) {
21755
22143
  }
21756
22144
  return null;
21757
22145
  }
21758
- function buildMagicContextSection(agent, protectedTags, ctxReduceEnabled = true) {
22146
+ function buildMagicContextSection(agent, protectedTags, ctxReduceEnabled = true, dreamerEnabled = false) {
22147
+ const smartNoteGuidance = dreamerEnabled ? `
22148
+ When \`surface_condition\` is provided with \`write\`, the note becomes a project-scoped smart note.
22149
+ The dreamer evaluates smart note conditions during nightly runs and surfaces them when conditions are met.
22150
+ Example: \`ctx_note(action="write", content="Implement X because Y", surface_condition="When PR #42 is merged in this repo")\`` : "";
21759
22151
  if (!ctxReduceEnabled) {
21760
22152
  return `## Magic Context
21761
22153
 
21762
- ${BASE_INTRO_NO_REDUCE}`;
22154
+ ${BASE_INTRO_NO_REDUCE}${smartNoteGuidance}`;
21763
22155
  }
21764
22156
  const section = agent ? AGENT_SECTIONS[agent] : GENERIC_SECTION;
21765
22157
  return `## Magic Context
21766
22158
 
21767
- ${BASE_INTRO(protectedTags)}
22159
+ ${BASE_INTRO(protectedTags)}${smartNoteGuidance}
21768
22160
  ${section}
21769
22161
 
21770
22162
  Prefer many small targeted operations over one large blanket operation. Compress early and often \u2014 don't wait for warnings.`;
@@ -21772,7 +22164,37 @@ Prefer many small targeted operations over one large blanket operation. Compress
21772
22164
 
21773
22165
  // src/hooks/magic-context/system-prompt-hash.ts
21774
22166
  var MAGIC_CONTEXT_MARKER = "## Magic Context";
22167
+ var PROJECT_DOCS_MARKER = "<project-docs>";
22168
+ var DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
22169
+ function readProjectDocs(directory) {
22170
+ const sections = [];
22171
+ for (const filename of DOC_FILES) {
22172
+ const filePath = join8(directory, filename);
22173
+ try {
22174
+ if (existsSync4(filePath)) {
22175
+ const content = readFileSync3(filePath, "utf-8").trim();
22176
+ if (content.length > 0) {
22177
+ sections.push(`<${filename}>
22178
+ ${content}
22179
+ </${filename}>`);
22180
+ }
22181
+ }
22182
+ } catch (error48) {
22183
+ log(`[magic-context] failed to read ${filename}:`, error48);
22184
+ }
22185
+ }
22186
+ if (sections.length === 0)
22187
+ return null;
22188
+ return `${PROJECT_DOCS_MARKER}
22189
+ ${sections.join(`
22190
+
22191
+ `)}
22192
+ </project-docs>`;
22193
+ }
21775
22194
  function createSystemPromptHashHandler(deps) {
22195
+ const stickyDateBySession = new Map;
22196
+ const cachedDocsBySession = new Map;
22197
+ const shouldInjectDocs = deps.dreamerEnabled && deps.injectDocs;
21776
22198
  return async (input, output) => {
21777
22199
  const sessionId = input.sessionID;
21778
22200
  if (!sessionId)
@@ -21781,10 +22203,47 @@ function createSystemPromptHashHandler(deps) {
21781
22203
  `);
21782
22204
  if (fullPrompt.length > 0 && !fullPrompt.includes(MAGIC_CONTEXT_MARKER)) {
21783
22205
  const detectedAgent = detectAgentFromSystemPrompt(fullPrompt);
21784
- const guidance = buildMagicContextSection(detectedAgent, deps.protectedTags, deps.ctxReduceEnabled);
22206
+ const guidance = buildMagicContextSection(detectedAgent, deps.protectedTags, deps.ctxReduceEnabled, deps.dreamerEnabled);
21785
22207
  output.system.push(guidance);
21786
22208
  sessionLog(sessionId, `injected ${detectedAgent ?? "generic"} guidance into system prompt`);
21787
22209
  }
22210
+ const isCacheBusting = deps.flushedSessions.has(sessionId);
22211
+ if (shouldInjectDocs) {
22212
+ const hasCached = cachedDocsBySession.has(sessionId);
22213
+ if (!hasCached || isCacheBusting) {
22214
+ const docsContent = readProjectDocs(deps.directory);
22215
+ cachedDocsBySession.set(sessionId, docsContent);
22216
+ if (docsContent && !hasCached) {
22217
+ sessionLog(sessionId, `loaded project docs (${docsContent.length} chars)`);
22218
+ } else if (docsContent && isCacheBusting) {
22219
+ sessionLog(sessionId, "refreshed project docs (cache-busting pass)");
22220
+ }
22221
+ }
22222
+ const docsBlock = cachedDocsBySession.get(sessionId);
22223
+ if (docsBlock && !fullPrompt.includes(PROJECT_DOCS_MARKER)) {
22224
+ output.system.push(docsBlock);
22225
+ }
22226
+ }
22227
+ const DATE_PATTERN = /Today's date: .+/;
22228
+ for (let i = 0;i < output.system.length; i++) {
22229
+ const match = output.system[i].match(DATE_PATTERN);
22230
+ if (!match)
22231
+ continue;
22232
+ const currentDate = match[0];
22233
+ const stickyDate = stickyDateBySession.get(sessionId);
22234
+ if (!stickyDate) {
22235
+ stickyDateBySession.set(sessionId, currentDate);
22236
+ } else if (currentDate !== stickyDate) {
22237
+ if (isCacheBusting) {
22238
+ stickyDateBySession.set(sessionId, currentDate);
22239
+ sessionLog(sessionId, `system prompt date updated: ${stickyDate} \u2192 ${currentDate} (cache-busting pass)`);
22240
+ } else {
22241
+ output.system[i] = output.system[i].replace(DATE_PATTERN, stickyDate);
22242
+ sessionLog(sessionId, `system prompt date frozen: real=${currentDate}, using=${stickyDate} (defer pass)`);
22243
+ }
22244
+ }
22245
+ break;
22246
+ }
21788
22247
  const systemContent = output.system.join(`
21789
22248
  `);
21790
22249
  if (systemContent.length === 0)
@@ -21974,6 +22433,9 @@ function createMagicContextHook(deps) {
21974
22433
  db,
21975
22434
  protectedTags: deps.config.protected_tags,
21976
22435
  ctxReduceEnabled,
22436
+ dreamerEnabled: deps.config.dreamer?.enabled === true,
22437
+ injectDocs: deps.config.dreamer?.inject_docs !== false,
22438
+ directory: deps.directory,
21977
22439
  flushedSessions,
21978
22440
  lastHeuristicsTurnId
21979
22441
  });
@@ -22040,6 +22502,7 @@ function createSessionHooks(args) {
22040
22502
  compactionHandler,
22041
22503
  config: {
22042
22504
  protected_tags: pluginConfig.protected_tags ?? DEFAULT_PROTECTED_TAGS,
22505
+ ctx_reduce_enabled: pluginConfig.ctx_reduce_enabled,
22043
22506
  nudge_interval_tokens: pluginConfig.nudge_interval_tokens ?? DEFAULT_NUDGE_INTERVAL_TOKENS,
22044
22507
  cache_ttl: pluginConfig.cache_ttl,
22045
22508
  auto_drop_tool_age: pluginConfig.auto_drop_tool_age,
@@ -22407,9 +22870,14 @@ var CTX_NOTE_DESCRIPTION = `Save or inspect durable session notes that persist f
22407
22870
  Use this for short goals, constraints, decisions, or reminders worth carrying forward.
22408
22871
 
22409
22872
  Actions:
22410
- - \`write\`: Append one note.
22411
- - \`read\`: Show current notes.
22412
- - \`clear\`: Remove all notes.
22873
+ - \`write\`: Append one note. Optionally provide \`surface_condition\` to create a smart note.
22874
+ - \`read\`: Show current notes (session notes + ready smart notes).
22875
+ - \`clear\`: Remove all session notes.
22876
+ - \`dismiss\`: Dismiss a ready smart note by \`note_id\`.
22877
+
22878
+ **Smart Notes**: When \`surface_condition\` is provided with \`write\`, the note becomes a project-scoped smart note.
22879
+ The dreamer evaluates smart note conditions during nightly runs and surfaces them when conditions are met.
22880
+ Example: \`ctx_note(action="write", content="Implement X because Y", surface_condition="When PR #42 is merged in this repo")\`
22413
22881
 
22414
22882
  Historian reads these notes, deduplicates them, and rewrites the remaining useful notes over time.`;
22415
22883
  // src/tools/ctx-note/tools.ts
@@ -22418,8 +22886,10 @@ function createCtxNoteTool(deps) {
22418
22886
  return tool3({
22419
22887
  description: CTX_NOTE_DESCRIPTION,
22420
22888
  args: {
22421
- action: tool3.schema.enum(["write", "read", "clear"]).optional().describe("Operation to perform. Defaults to 'write' when content is provided, otherwise 'read'."),
22422
- content: tool3.schema.string().optional().describe("Note text to store when action is 'write'.")
22889
+ action: tool3.schema.enum(["write", "read", "clear", "dismiss"]).optional().describe("Operation to perform. Defaults to 'write' when content is provided, otherwise 'read'."),
22890
+ content: tool3.schema.string().optional().describe("Note text to store when action is 'write'."),
22891
+ surface_condition: tool3.schema.string().optional().describe("Open-ended condition for smart notes. When provided, creates a project-scoped smart note that the dreamer evaluates nightly. The note surfaces when the condition is met."),
22892
+ note_id: tool3.schema.number().optional().describe("Smart note ID to dismiss (required for 'dismiss' action).")
22423
22893
  },
22424
22894
  async execute(args, toolContext) {
22425
22895
  const sessionId = toolContext.sessionID;
@@ -22429,26 +22899,63 @@ function createCtxNoteTool(deps) {
22429
22899
  if (!content) {
22430
22900
  return "Error: 'content' is required when action is 'write'.";
22431
22901
  }
22902
+ if (args.surface_condition?.trim()) {
22903
+ if (!deps.dreamerEnabled) {
22904
+ return "Error: Smart notes require dreamer to be enabled. Enable dreamer in magic-context.jsonc to use surface_condition.";
22905
+ }
22906
+ if (!deps.projectIdentity) {
22907
+ return "Error: Could not resolve project identity for smart note.";
22908
+ }
22909
+ const note = addSmartNote(deps.db, deps.projectIdentity, content, args.surface_condition.trim(), sessionId);
22910
+ return `Created smart note #${note.id}. Dreamer will evaluate the condition during nightly runs:
22911
+ - Content: ${content}
22912
+ - Condition: ${args.surface_condition.trim()}`;
22913
+ }
22432
22914
  addSessionNote(deps.db, sessionId, content);
22433
22915
  const total = getSessionNotes(deps.db, sessionId).length;
22434
22916
  return `Saved session note ${total}. Historian will rewrite or deduplicate notes as needed.`;
22435
22917
  }
22918
+ if (action === "dismiss") {
22919
+ const noteId = args.note_id;
22920
+ if (typeof noteId !== "number") {
22921
+ return "Error: 'note_id' is required when action is 'dismiss'.";
22922
+ }
22923
+ const dismissed = dismissSmartNote(deps.db, noteId);
22924
+ return dismissed ? `Smart note #${noteId} dismissed.` : `Smart note #${noteId} not found or already dismissed.`;
22925
+ }
22436
22926
  if (action === "clear") {
22437
22927
  const existing = getSessionNotes(deps.db, sessionId);
22438
22928
  clearSessionNotes(deps.db, sessionId);
22439
22929
  return existing.length === 0 ? "Session notes were already empty." : `Cleared ${existing.length} session note${existing.length === 1 ? "" : "s"}.`;
22440
22930
  }
22441
22931
  const notes = getSessionNotes(deps.db, sessionId);
22442
- if (notes.length === 0) {
22443
- return `## Session Notes
22932
+ const readySmartNotes = deps.projectIdentity ? getReadySmartNotes(deps.db, deps.projectIdentity) : [];
22933
+ const sections = [];
22934
+ if (notes.length > 0) {
22935
+ const lines = notes.map((note, index) => `${index + 1}. ${note.content}`);
22936
+ sections.push(`## Session Notes
22444
22937
 
22445
- No session notes saved yet.`;
22938
+ ${lines.join(`
22939
+ `)}`);
22446
22940
  }
22447
- const lines = notes.map((note, index) => `${index + 1}. ${note.content}`);
22448
- return `## Session Notes
22941
+ if (readySmartNotes.length > 0) {
22942
+ const lines = readySmartNotes.map((n) => `- **#${n.id}**: ${n.content}
22943
+ Condition met: ${n.readyReason ?? n.surfaceCondition}
22944
+ _(dismiss with \`ctx_note(action="dismiss", note_id=${n.id})\`)_`);
22945
+ sections.push(`## \uD83D\uDD14 Ready Smart Notes
22449
22946
 
22450
22947
  ${lines.join(`
22451
- `)}`;
22948
+
22949
+ `)}`);
22950
+ }
22951
+ if (sections.length === 0) {
22952
+ return `## Notes
22953
+
22954
+ No session notes or smart notes.`;
22955
+ }
22956
+ return sections.join(`
22957
+
22958
+ `);
22452
22959
  }
22453
22960
  });
22454
22961
  }
@@ -23037,7 +23544,11 @@ function createToolRegistry(args) {
23037
23544
  protectedTags: pluginConfig.protected_tags ?? DEFAULT_PROTECTED_TAGS
23038
23545
  }) : {},
23039
23546
  ...createCtxExpandTools(),
23040
- ...createCtxNoteTools({ db }),
23547
+ ...createCtxNoteTools({
23548
+ db,
23549
+ dreamerEnabled: pluginConfig.dreamer?.enabled === true,
23550
+ projectIdentity: projectPath
23551
+ }),
23041
23552
  ...createCtxSearchTools({
23042
23553
  db,
23043
23554
  projectPath,
@@ -23061,20 +23572,20 @@ function createToolRegistry(args) {
23061
23572
  }
23062
23573
 
23063
23574
  // src/shared/opencode-compaction-detector.ts
23064
- import { join as join9 } from "path";
23575
+ import { join as join10 } from "path";
23065
23576
 
23066
23577
  // src/shared/opencode-config-dir.ts
23067
23578
  import { homedir as homedir3 } from "os";
23068
- import { join as join8, resolve } from "path";
23579
+ import { join as join9, resolve } from "path";
23069
23580
  function getCliConfigDir() {
23070
23581
  const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
23071
23582
  if (envConfigDir) {
23072
23583
  return resolve(envConfigDir);
23073
23584
  }
23074
23585
  if (process.platform === "win32") {
23075
- return join8(homedir3(), ".config", "opencode");
23586
+ return join9(homedir3(), ".config", "opencode");
23076
23587
  }
23077
- return join8(process.env.XDG_CONFIG_HOME || join8(homedir3(), ".config"), "opencode");
23588
+ return join9(process.env.XDG_CONFIG_HOME || join9(homedir3(), ".config"), "opencode");
23078
23589
  }
23079
23590
  function getOpenCodeConfigDir(_options) {
23080
23591
  return getCliConfigDir();
@@ -23083,10 +23594,10 @@ function getOpenCodeConfigPaths(options) {
23083
23594
  const configDir = getOpenCodeConfigDir(options);
23084
23595
  return {
23085
23596
  configDir,
23086
- configJson: join8(configDir, "opencode.json"),
23087
- configJsonc: join8(configDir, "opencode.jsonc"),
23088
- packageJson: join8(configDir, "package.json"),
23089
- omoConfig: join8(configDir, "magic-context.jsonc")
23597
+ configJson: join9(configDir, "opencode.json"),
23598
+ configJsonc: join9(configDir, "opencode.jsonc"),
23599
+ packageJson: join9(configDir, "package.json"),
23600
+ omoConfig: join9(configDir, "magic-context.jsonc")
23090
23601
  };
23091
23602
  }
23092
23603
 
@@ -23118,15 +23629,15 @@ function isOpenCodeAutoCompactionEnabled(directory) {
23118
23629
  return true;
23119
23630
  }
23120
23631
  function readProjectCompactionConfig(directory) {
23121
- const dotOpenCodeJsonc = join9(directory, ".opencode", "opencode.jsonc");
23122
- const dotOpenCodeJson = join9(directory, ".opencode", "opencode.json");
23632
+ const dotOpenCodeJsonc = join10(directory, ".opencode", "opencode.jsonc");
23633
+ const dotOpenCodeJson = join10(directory, ".opencode", "opencode.json");
23123
23634
  const dotOpenCodeConfig = readJsoncFile(dotOpenCodeJsonc) ?? readJsoncFile(dotOpenCodeJson);
23124
23635
  const dotOpenCodeCompactionConflict = hasCompactionConflict(dotOpenCodeConfig?.compaction);
23125
23636
  if (dotOpenCodeCompactionConflict !== undefined) {
23126
23637
  return dotOpenCodeCompactionConflict;
23127
23638
  }
23128
- const rootJsonc = join9(directory, "opencode.jsonc");
23129
- const rootJson = join9(directory, "opencode.json");
23639
+ const rootJsonc = join10(directory, "opencode.jsonc");
23640
+ const rootJson = join10(directory, "opencode.json");
23130
23641
  const rootConfig = readJsoncFile(rootJsonc) ?? readJsoncFile(rootJson);
23131
23642
  return hasCompactionConflict(rootConfig?.compaction);
23132
23643
  }