@oxgeneral/orch 1.0.2 → 1.0.4

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 (132) hide show
  1. package/dist/App-SSYYVFGW.js +22 -0
  2. package/dist/agent-Q34L27AY.js +9 -0
  3. package/dist/agent-shop-D2RS4BZK.js +2 -0
  4. package/dist/chunk-4MMHVHA6.js +112 -0
  5. package/dist/chunk-64WUDYEM.js +6 -0
  6. package/dist/chunk-6MJ7V6VY.js +2 -0
  7. package/dist/{chunk-DAVHOWGD.js → chunk-BCPUTULS.js} +16 -188
  8. package/dist/{chunk-INZ4O2RI.js → chunk-BSJVYRI3.js} +5 -2
  9. package/dist/chunk-BSJVYRI3.js.map +1 -0
  10. package/dist/chunk-CDFA4IIQ.js +2 -0
  11. package/dist/chunk-CHRW4CLD.js +2 -0
  12. package/dist/chunk-HMMPM7MF.js +3 -0
  13. package/dist/chunk-HXOMNULD.js +2 -0
  14. package/dist/chunk-IKNBPOQL.js +2 -0
  15. package/dist/chunk-KFQTWMZI.js +3 -0
  16. package/dist/chunk-LXNRCJ22.js +2 -0
  17. package/dist/{chunk-C6XZ3FJT.js → chunk-MOWC2CHX.js} +7 -4
  18. package/dist/chunk-MOWC2CHX.js.map +1 -0
  19. package/dist/chunk-P4JTJBWO.js +2 -0
  20. package/dist/chunk-PJ5DKXGR.js +2 -0
  21. package/dist/chunk-QNZ6D63E.js +4 -0
  22. package/dist/chunk-RHFRHCN5.js +16 -0
  23. package/dist/chunk-RHFRHCN5.js.map +1 -0
  24. package/dist/chunk-TPTHLFOB.js +2 -0
  25. package/dist/chunk-UMZEA3JT.js +5 -0
  26. package/dist/chunk-X54D5JZG.js +11 -0
  27. package/dist/{chunk-O2OQCSBL.js → chunk-YHIYJ5OL.js} +105 -29
  28. package/dist/chunk-YHIYJ5OL.js.map +1 -0
  29. package/dist/{claude-WUJU5KIE.js → claude-4R6L6BWY.js} +4 -4
  30. package/dist/{claude-WUJU5KIE.js.map → claude-4R6L6BWY.js.map} +1 -1
  31. package/dist/claude-ZLVOLRUG.js +2 -0
  32. package/dist/cli.js +1 -213
  33. package/dist/clipboard-service-WVON5ZN4.js +25 -0
  34. package/dist/{codex-NYJWEPRQ.js → codex-IMOW5ZUZ.js} +4 -4
  35. package/dist/{codex-NYJWEPRQ.js.map → codex-IMOW5ZUZ.js.map} +1 -1
  36. package/dist/codex-YRSODLH4.js +2 -0
  37. package/dist/config-OOB7QEKM.js +2 -0
  38. package/dist/container-FJI7RN2L.js +4 -0
  39. package/dist/context-FXRERFSP.js +7 -0
  40. package/dist/cursor-2HILMNM3.js +2 -0
  41. package/dist/{cursor-3YHVD4NP.js → cursor-NHV7X3WG.js} +4 -4
  42. package/dist/{cursor-3YHVD4NP.js.map → cursor-NHV7X3WG.js.map} +1 -1
  43. package/dist/doctor-GKTV4YYD.js +2 -0
  44. package/dist/doctor-service-PB7YBH3F.js +2 -0
  45. package/dist/editor-7IFRWVTL.js +8 -0
  46. package/dist/goal-RNNZYMNR.js +8 -0
  47. package/dist/index.d.ts +26 -8
  48. package/dist/index.js +247 -75
  49. package/dist/index.js.map +1 -1
  50. package/dist/init-56QC5QVX.js +53 -0
  51. package/dist/logs-4ISTWUWV.js +12 -0
  52. package/dist/msg-4ELI7Q52.js +9 -0
  53. package/dist/opencode-3S4VDXRG.js +2 -0
  54. package/dist/{opencode-FAMPSA6X.js → opencode-ULT6DYCT.js} +6 -5
  55. package/dist/opencode-ULT6DYCT.js.map +1 -0
  56. package/dist/orchestrator-PM4BW7W5.js +13 -0
  57. package/dist/orchestrator-QFNYZ6AH.js +6 -0
  58. package/dist/{orchestrator-X2CWGFCL.js.map → orchestrator-QFNYZ6AH.js.map} +1 -1
  59. package/dist/org-WAK3CDPG.js +3 -0
  60. package/dist/process-manager-33H27MQF.js +2 -0
  61. package/dist/registry-BO2PPRNG.js +2 -0
  62. package/dist/run-NE5E4JPW.js +3 -0
  63. package/dist/shell-OBHIVC2H.js +2 -0
  64. package/dist/{shell-NJNW3O6K.js → shell-UXEJRK3D.js} +4 -4
  65. package/dist/{shell-NJNW3O6K.js.map → shell-UXEJRK3D.js.map} +1 -1
  66. package/dist/shop-picker-LE3SKFOX.js +5 -0
  67. package/dist/status-NYHZ7Q5G.js +2 -0
  68. package/dist/task-SZBYNAZP.js +20 -0
  69. package/dist/team-VCJSUDWX.js +4 -0
  70. package/dist/template-engine-42PKL5KD.js +2 -0
  71. package/dist/tui-4VRDSRVB.js +2 -0
  72. package/dist/update-FFKCOV63.js +2 -0
  73. package/dist/update-check-HGMBDYHL.js +2 -0
  74. package/dist/{workspace-manager-2SFPKPLZ.js → workspace-manager-ABXFBL2A.js} +3 -3
  75. package/dist/{workspace-manager-2SFPKPLZ.js.map → workspace-manager-ABXFBL2A.js.map} +1 -1
  76. package/dist/workspace-manager-Q6WWXSTR.js +3 -0
  77. package/package.json +1 -1
  78. package/dist/App-YQOT4LBE.js +0 -6727
  79. package/dist/agent-7ZJ3ZDJ7.js +0 -183
  80. package/dist/agent-shop-YN2BSLHM.js +0 -2
  81. package/dist/chunk-2C2TFQ7K.js +0 -136
  82. package/dist/chunk-45K2XID7.js +0 -29
  83. package/dist/chunk-4IFIOMCW.js +0 -86
  84. package/dist/chunk-7X2GI5OV.js +0 -181
  85. package/dist/chunk-C6XZ3FJT.js.map +0 -1
  86. package/dist/chunk-CHIP7O6V.js +0 -83
  87. package/dist/chunk-FRTKB575.js +0 -87
  88. package/dist/chunk-HXYAZGLP.js +0 -15
  89. package/dist/chunk-I3SMISEF.js +0 -29
  90. package/dist/chunk-INZ4O2RI.js.map +0 -1
  91. package/dist/chunk-ITLJKMTP.js +0 -297
  92. package/dist/chunk-K6DMQERQ.js +0 -89
  93. package/dist/chunk-MGGSRXWJ.js +0 -69
  94. package/dist/chunk-O2OQCSBL.js.map +0 -1
  95. package/dist/chunk-P6ATSXGL.js +0 -107
  96. package/dist/chunk-PNE6LQRF.js +0 -5
  97. package/dist/chunk-U2VDNUZL.js +0 -52
  98. package/dist/chunk-VXS2CJFH.js +0 -273
  99. package/dist/chunk-XDVMX2FO.js +0 -8
  100. package/dist/chunk-XDVMX2FO.js.map +0 -1
  101. package/dist/chunk-XJTJ2TJV.js +0 -221
  102. package/dist/claude-ZUEKJJ4X.js +0 -5
  103. package/dist/clipboard-service-RTDUUQQU.js +0 -200
  104. package/dist/codex-7IXXXG5U.js +0 -123
  105. package/dist/config-OTAVSMOD.js +0 -75
  106. package/dist/container-IZZVO4AH.js +0 -1596
  107. package/dist/context-OL4BVUV5.js +0 -83
  108. package/dist/cursor-622RBRHH.js +0 -97
  109. package/dist/doctor-SETNAS4S.js +0 -67
  110. package/dist/doctor-service-TPOMFAIG.js +0 -2
  111. package/dist/goal-C6YGSX5D.js +0 -143
  112. package/dist/init-SWAAXP5H.js +0 -199
  113. package/dist/logs-PHPYWQ6I.js +0 -207
  114. package/dist/msg-FUWWLEKM.js +0 -95
  115. package/dist/opencode-FAMPSA6X.js.map +0 -1
  116. package/dist/opencode-WOR53TSC.js +0 -98
  117. package/dist/orchestrator-O6MFMATT.js +0 -1448
  118. package/dist/orchestrator-X2CWGFCL.js +0 -5
  119. package/dist/org-JSMMBZHI.js +0 -249
  120. package/dist/process-manager-HUVNAPQV.js +0 -2
  121. package/dist/registry-PQWRVNF2.js +0 -2
  122. package/dist/run-N72G5V2H.js +0 -95
  123. package/dist/shell-DVFHHYAZ.js +0 -5
  124. package/dist/shop-picker-2HY67UWP.js +0 -79
  125. package/dist/status-RZWN2C6C.js +0 -56
  126. package/dist/task-XNYZHPCS.js +0 -221
  127. package/dist/team-PFLP4PPL.js +0 -97
  128. package/dist/template-engine-AWIS56BL.js +0 -3
  129. package/dist/tui-JW3DOOKH.js +0 -245
  130. package/dist/update-YLP7FPNY.js +0 -64
  131. package/dist/update-check-4YKLGBFB.js +0 -2
  132. package/dist/workspace-manager-ESPU7WOH.js +0 -215
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
- import { ensureDir, Paths, readYaml, writeYaml, listFiles, writeJson, readJson, appendJsonl, readJsonl, readJsonlTail, pathExists } from './chunk-INZ4O2RI.js';
2
- import { canTransition, isTerminal } from './chunk-O2OQCSBL.js';
3
- export { Orchestrator, canTransition, isBlocked, isDispatchable, isTerminal, resolveFailureStatus } from './chunk-O2OQCSBL.js';
1
+ import { ensureDir, Paths, readYaml, writeYaml, readJson, writeJson, listFiles, appendJsonl, readJsonl, readJsonlTail, pathExists } from './chunk-BSJVYRI3.js';
2
+ import { canTransition, isTerminal } from './chunk-YHIYJ5OL.js';
3
+ export { Orchestrator, canTransition, isBlocked, isDispatchable, isTerminal, resolveFailureStatus } from './chunk-YHIYJ5OL.js';
4
4
  import { AUTONOMOUS_LABEL } from './chunk-VG4465AG.js';
5
5
  export { AdapterRegistry } from './chunk-6DWHQPTE.js';
6
- export { createTokenUsage } from './chunk-XDVMX2FO.js';
6
+ export { createTokenUsage } from './chunk-RHFRHCN5.js';
7
7
  import { InvalidArgumentsError, TaskNotFoundError, InvalidTransitionError, AgentNotFoundError, OrchestryError, TeamNotFoundError, GoalNotFoundError } from './chunk-NLQAJ7TW.js';
8
8
  export { AdapterErrorKind, AgentNotFoundError, ERROR_HINTS, NotInitializedError, OrchestryError, TaskNotFoundError, WorkspaceError, classifyAdapterError } from './chunk-NLQAJ7TW.js';
9
9
  import fs, { mkdtemp, readFile, unlink, rm, mkdir } from 'fs/promises';
@@ -748,20 +748,138 @@ async function getImageWindows() {
748
748
  }
749
749
  }
750
750
  }
751
+
752
+ // src/domain/global-config.ts
753
+ var DEFAULT_GLOBAL_CONFIG = {
754
+ tui: {
755
+ activity_filter: "all",
756
+ notifications: { toast: true, bell: false }
757
+ }
758
+ };
759
+ var IndexManager = class {
760
+ indexPath;
761
+ dir;
762
+ ext;
763
+ itemPath;
764
+ fileFilter;
765
+ readItemFn;
766
+ /** Promise-chain mutex to serialize updateIndex read-modify-write cycles. */
767
+ mutex = Promise.resolve();
768
+ /** True while executing inside withMutex — prevents re-entrant deadlock. */
769
+ insideMutex = false;
770
+ constructor(config) {
771
+ this.dir = config.dir;
772
+ this.ext = config.ext;
773
+ this.itemPath = config.itemPath;
774
+ this.indexPath = path.join(config.dir, "_index.json");
775
+ this.fileFilter = config.fileFilter ?? (() => true);
776
+ if (config.readItem) {
777
+ this.readItemFn = config.readItem;
778
+ } else if (config.ext === ".yml") {
779
+ this.readItemFn = (fp) => readYaml(fp);
780
+ } else {
781
+ this.readItemFn = (fp) => readJson(fp);
782
+ }
783
+ }
784
+ /**
785
+ * Read the index file. Falls back to rebuilding from individual files
786
+ * if the index is missing or corrupt.
787
+ */
788
+ async readIndex() {
789
+ try {
790
+ const entries = await readJson(this.indexPath);
791
+ if (Array.isArray(entries)) return entries;
792
+ } catch {
793
+ }
794
+ return this.rebuildIndex();
795
+ }
796
+ /**
797
+ * Rebuild the index by reading all individual item files.
798
+ * Used as fallback when _index.json is missing or corrupted.
799
+ *
800
+ * When called from outside the mutex (standalone), the write is serialized
801
+ * through {@link withMutex} to prevent races with concurrent updateIndex.
802
+ * When called from within the mutex (e.g. updateIndex → readIndex fallback),
803
+ * it writes directly to avoid re-entrant deadlock.
804
+ */
805
+ async rebuildIndex() {
806
+ await ensureDir(this.dir);
807
+ const files = await listFiles(this.dir, this.ext);
808
+ const results = await Promise.all(
809
+ files.filter(this.fileFilter).map((file) => {
810
+ const id = file.replace(this.ext, "");
811
+ return this.readItemFn(this.itemPath(id));
812
+ })
813
+ );
814
+ const items = [];
815
+ for (const item of results) {
816
+ if (item != null) items.push(item);
817
+ }
818
+ if (this.insideMutex) {
819
+ await this.writeIndexUnsafe(items);
820
+ } else {
821
+ await this.withMutex(() => this.writeIndexUnsafe(items));
822
+ }
823
+ return items;
824
+ }
825
+ /**
826
+ * Write the index file atomically.
827
+ * Serialized through the mutex to prevent races with concurrent updateIndex.
828
+ */
829
+ async writeIndex(items) {
830
+ return this.withMutex(() => this.writeIndexUnsafe(items));
831
+ }
832
+ /**
833
+ * Apply a mutation to the index and write it back.
834
+ *
835
+ * Serialized through a promise-chain mutex to prevent TOCTOU races
836
+ * where parallel callers could overwrite each other's changes
837
+ * (e.g. two `orch task add` invocations losing data).
838
+ */
839
+ async updateIndex(fn) {
840
+ return this.withMutex(async () => {
841
+ const current = await this.readIndex();
842
+ const updated = fn(current);
843
+ await this.writeIndexUnsafe(updated);
844
+ });
845
+ }
846
+ /** Internal write without mutex — called only from within withMutex. */
847
+ async writeIndexUnsafe(items) {
848
+ await ensureDir(this.dir);
849
+ await writeJson(this.indexPath, items);
850
+ }
851
+ /** Promise-chain mutex: serializes all index-mutating operations. */
852
+ withMutex(fn) {
853
+ let release;
854
+ const next = new Promise((resolve) => {
855
+ release = resolve;
856
+ });
857
+ const prev = this.mutex;
858
+ this.mutex = next;
859
+ return prev.then(async () => {
860
+ this.insideMutex = true;
861
+ try {
862
+ return await fn();
863
+ } finally {
864
+ this.insideMutex = false;
865
+ release();
866
+ }
867
+ });
868
+ }
869
+ };
751
870
  var TaskStore = class {
752
871
  constructor(paths) {
753
872
  this.paths = paths;
873
+ this.index = new IndexManager({
874
+ dir: paths.tasksDir,
875
+ ext: ".yml",
876
+ itemPath: (id) => paths.taskPath(id)
877
+ });
754
878
  }
879
+ index;
755
880
  async list(filter) {
756
- await ensureDir(this.paths.tasksDir);
757
- const files = await listFiles(this.paths.tasksDir, ".yml");
758
- const tasksResults = await Promise.all(
759
- files.map((file) => {
760
- const id = file.replace(".yml", "");
761
- return readYaml(this.paths.taskPath(id));
762
- })
763
- );
764
- const tasks = tasksResults.filter(
881
+ const all = await this.index.readIndex();
882
+ const tasks = all.filter(
765
883
  (task) => task !== null && (!filter?.status || task.status === filter.status) && (!filter?.goalId || task.goalId === filter.goalId)
766
884
  );
767
885
  return tasks.sort((a, b) => {
@@ -778,6 +896,11 @@ var TaskStore = class {
778
896
  async save(task) {
779
897
  await ensureDir(this.paths.tasksDir);
780
898
  await writeYaml(this.paths.taskPath(task.id), task);
899
+ await this.index.updateIndex((idx) => {
900
+ const filtered = idx.filter((t) => t.id !== task.id);
901
+ filtered.push(task);
902
+ return filtered;
903
+ });
781
904
  }
782
905
  async delete(id) {
783
906
  try {
@@ -785,6 +908,7 @@ var TaskStore = class {
785
908
  } catch (err) {
786
909
  if (err.code !== "ENOENT") throw err;
787
910
  }
911
+ await this.index.updateIndex((idx) => idx.filter((t) => t.id !== id));
788
912
  }
789
913
  };
790
914
  function statusPriority(status) {
@@ -802,17 +926,15 @@ function statusPriority(status) {
802
926
  var AgentStore = class {
803
927
  constructor(paths) {
804
928
  this.paths = paths;
929
+ this.index = new IndexManager({
930
+ dir: paths.agentsDir,
931
+ ext: ".yml",
932
+ itemPath: (id) => paths.agentPath(id)
933
+ });
805
934
  }
935
+ index;
806
936
  async list() {
807
- await ensureDir(this.paths.agentsDir);
808
- const files = await listFiles(this.paths.agentsDir, ".yml");
809
- const results = await Promise.all(
810
- files.map((file) => {
811
- const id = file.replace(".yml", "");
812
- return readYaml(this.paths.agentPath(id));
813
- })
814
- );
815
- return results.filter((agent) => agent !== null);
937
+ return this.index.readIndex();
816
938
  }
817
939
  async get(id) {
818
940
  return readYaml(this.paths.agentPath(id));
@@ -824,6 +946,11 @@ var AgentStore = class {
824
946
  async save(agent) {
825
947
  await ensureDir(this.paths.agentsDir);
826
948
  await writeYaml(this.paths.agentPath(agent.id), agent);
949
+ await this.index.updateIndex((idx) => {
950
+ const filtered = idx.filter((a) => a.id !== agent.id);
951
+ filtered.push(agent);
952
+ return filtered;
953
+ });
827
954
  }
828
955
  async delete(id) {
829
956
  try {
@@ -831,6 +958,7 @@ var AgentStore = class {
831
958
  } catch (err) {
832
959
  if (err.code !== "ENOENT") throw err;
833
960
  }
961
+ await this.index.updateIndex((idx) => idx.filter((a) => a.id !== id));
834
962
  }
835
963
  };
836
964
  var RunStore = class {
@@ -926,7 +1054,7 @@ var DEFAULT_STATE = {
926
1054
  total_runs: 0,
927
1055
  total_tasks_completed: 0,
928
1056
  total_tasks_failed: 0,
929
- total_tokens: { input: 0, output: 0, total: 0 },
1057
+ total_tokens: { input: 0, output: 0, reasoning: 0, total: 0, cache_read: 0, cache_write: 0 },
930
1058
  total_runtime_ms: 0
931
1059
  }
932
1060
  };
@@ -952,7 +1080,10 @@ var StateStore = class {
952
1080
  total_runs: raw.stats?.total_runs ?? defaults.stats.total_runs,
953
1081
  total_tasks_completed: raw.stats?.total_tasks_completed ?? defaults.stats.total_tasks_completed,
954
1082
  total_tasks_failed: raw.stats?.total_tasks_failed ?? defaults.stats.total_tasks_failed,
955
- total_tokens: raw.stats?.total_tokens ?? defaults.stats.total_tokens,
1083
+ total_tokens: {
1084
+ ...defaults.stats.total_tokens,
1085
+ ...raw.stats?.total_tokens ?? {}
1086
+ },
956
1087
  total_runtime_ms: raw.stats?.total_runtime_ms ?? defaults.stats.total_runtime_ms
957
1088
  }
958
1089
  };
@@ -1055,16 +1186,6 @@ function deepMerge(target, source) {
1055
1186
  }
1056
1187
  return result;
1057
1188
  }
1058
-
1059
- // src/domain/global-config.ts
1060
- var DEFAULT_GLOBAL_CONFIG = {
1061
- tui: {
1062
- activity_filter: "all",
1063
- notifications: { toast: true, bell: false }
1064
- }
1065
- };
1066
-
1067
- // src/infrastructure/storage/global-config-store.ts
1068
1189
  var GLOBAL_DIR = path.join(homedir(), ".orchestry");
1069
1190
  var GLOBAL_CONFIG_PATH = path.join(GLOBAL_DIR, "global.yml");
1070
1191
  var GlobalConfigStore = class {
@@ -1096,7 +1217,14 @@ var GlobalConfigStore = class {
1096
1217
  var ContextStore = class _ContextStore {
1097
1218
  constructor(paths) {
1098
1219
  this.paths = paths;
1220
+ this.index = new IndexManager({
1221
+ dir: paths.contextDir,
1222
+ ext: ".json",
1223
+ itemPath: (key) => paths.contextPath(key),
1224
+ fileFilter: (f) => f !== "_index.json"
1225
+ });
1099
1226
  }
1227
+ index;
1100
1228
  async get(key) {
1101
1229
  const entry = await readJson(this.paths.contextPath(key));
1102
1230
  if (!entry) return null;
@@ -1126,6 +1254,11 @@ var ContextStore = class _ContextStore {
1126
1254
  expires_at: ttlMs ? new Date(Date.now() + ttlMs).toISOString() : void 0
1127
1255
  };
1128
1256
  await writeJson(this.paths.contextPath(key), entry);
1257
+ await this.index.updateIndex((idx) => {
1258
+ const filtered = idx.filter((e) => e.key !== key);
1259
+ filtered.push(entry);
1260
+ return filtered;
1261
+ });
1129
1262
  }
1130
1263
  async delete(key) {
1131
1264
  try {
@@ -1133,26 +1266,24 @@ var ContextStore = class _ContextStore {
1133
1266
  } catch (err) {
1134
1267
  if (err.code !== "ENOENT") throw err;
1135
1268
  }
1269
+ await this.index.updateIndex((idx) => idx.filter((e) => e.key !== key));
1136
1270
  }
1137
1271
  async list() {
1138
- await ensureDir(this.paths.contextDir);
1139
- const files = await listFiles(this.paths.contextDir, ".json");
1140
- const results = await Promise.all(
1141
- files.map((file) => {
1142
- const key = file.replace(".json", "");
1143
- return readJson(this.paths.contextPath(key));
1144
- })
1145
- );
1146
- const entries = [];
1147
- for (const entry of results) {
1148
- if (!entry) continue;
1272
+ const entries = await this.index.readIndex();
1273
+ const expired = [];
1274
+ const valid = [];
1275
+ for (const entry of entries) {
1149
1276
  if (isExpired(entry)) {
1150
- await this.delete(entry.key);
1151
- continue;
1277
+ expired.push(entry);
1278
+ } else {
1279
+ valid.push(entry);
1152
1280
  }
1153
- entries.push(entry);
1154
1281
  }
1155
- return entries.sort((a, b) => a.key.localeCompare(b.key));
1282
+ if (expired.length > 0) {
1283
+ await Promise.all(expired.map((e) => this.deleteFile(e.key)));
1284
+ await this.index.writeIndex(valid);
1285
+ }
1286
+ return valid.sort((a, b) => a.key.localeCompare(b.key));
1156
1287
  }
1157
1288
  async getAll() {
1158
1289
  const entries = await this.list();
@@ -1162,6 +1293,14 @@ var ContextStore = class _ContextStore {
1162
1293
  }
1163
1294
  return result;
1164
1295
  }
1296
+ /** Delete just the file (no index update). Used by lazy expiry cleanup. */
1297
+ async deleteFile(key) {
1298
+ try {
1299
+ await fs.unlink(this.paths.contextPath(key));
1300
+ } catch (err) {
1301
+ if (err.code !== "ENOENT") throw err;
1302
+ }
1303
+ }
1165
1304
  };
1166
1305
  function isExpired(entry) {
1167
1306
  if (!entry.expires_at) return false;
@@ -1170,20 +1309,29 @@ function isExpired(entry) {
1170
1309
  var MessageStore = class {
1171
1310
  constructor(paths) {
1172
1311
  this.paths = paths;
1312
+ this.index = new IndexManager({
1313
+ dir: paths.messagesDir,
1314
+ ext: ".json",
1315
+ itemPath: (id) => paths.messagePath(id),
1316
+ fileFilter: (fileName) => fileName !== "_index.json"
1317
+ });
1173
1318
  }
1319
+ index;
1174
1320
  async save(message) {
1175
1321
  await ensureDir(this.paths.messagesDir);
1176
1322
  await writeJson(this.paths.messagePath(message.id), message);
1323
+ await this.index.updateIndex((idx) => {
1324
+ const filtered = idx.filter((m) => m.id !== message.id);
1325
+ filtered.push(message);
1326
+ return filtered;
1327
+ });
1177
1328
  }
1178
1329
  async get(id) {
1179
1330
  return readJson(this.paths.messagePath(id));
1180
1331
  }
1181
1332
  async list() {
1182
- const files = await listFiles(this.paths.messagesDir, ".json");
1183
- const results = await Promise.all(
1184
- files.map((f) => readJson(this.paths.messagePath(f.replace(".json", ""))))
1185
- );
1186
- return results.filter((m) => m !== null).sort((a, b) => a.created_at.localeCompare(b.created_at));
1333
+ const all = await this.index.readIndex();
1334
+ return all.filter((m) => m !== null).sort((a, b) => a.created_at.localeCompare(b.created_at));
1187
1335
  }
1188
1336
  async listPending(agentId) {
1189
1337
  const all = await this.list();
@@ -1200,6 +1348,11 @@ var MessageStore = class {
1200
1348
  msg.status = "delivered";
1201
1349
  msg.delivered_at = (/* @__PURE__ */ new Date()).toISOString();
1202
1350
  await writeJson(this.paths.messagePath(id), msg);
1351
+ await this.index.updateIndex((idx) => {
1352
+ const filtered = idx.filter((m) => m.id !== id);
1353
+ filtered.push(msg);
1354
+ return filtered;
1355
+ });
1203
1356
  }
1204
1357
  async delete(id) {
1205
1358
  try {
@@ -1207,6 +1360,7 @@ var MessageStore = class {
1207
1360
  } catch (err) {
1208
1361
  if (err.code !== "ENOENT") throw err;
1209
1362
  }
1363
+ await this.index.updateIndex((idx) => idx.filter((m) => m.id !== id));
1210
1364
  }
1211
1365
  async purgeExpired() {
1212
1366
  const all = await this.list();
@@ -1216,7 +1370,17 @@ var MessageStore = class {
1216
1370
  const isOldDelivered = m.delivered_at && now - new Date(m.delivered_at).getTime() > 36e5;
1217
1371
  return isExpired2 || isOldDelivered;
1218
1372
  });
1219
- await Promise.all(toDelete.map((m) => this.delete(m.id)));
1373
+ const idsToDelete = new Set(toDelete.map((m) => m.id));
1374
+ await Promise.all(
1375
+ toDelete.map(async (m) => {
1376
+ try {
1377
+ await fs.unlink(this.paths.messagePath(m.id));
1378
+ } catch (err) {
1379
+ if (err.code !== "ENOENT") throw err;
1380
+ }
1381
+ })
1382
+ );
1383
+ await this.index.updateIndex((idx) => idx.filter((m) => !idsToDelete.has(m.id)));
1220
1384
  return toDelete.length;
1221
1385
  }
1222
1386
  };
@@ -1235,16 +1399,16 @@ var GOAL_STATUS_ORDER = {
1235
1399
  var GoalStore = class {
1236
1400
  constructor(paths) {
1237
1401
  this.paths = paths;
1402
+ this.index = new IndexManager({
1403
+ dir: paths.goalsDir,
1404
+ ext: ".yml",
1405
+ itemPath: (id) => paths.goalPath(id)
1406
+ });
1238
1407
  }
1408
+ index;
1239
1409
  async list(filter) {
1240
- const files = await listFiles(this.paths.goalsDir, ".yml");
1241
- const results = await Promise.all(
1242
- files.map((file) => {
1243
- const id = file.replace(".yml", "");
1244
- return readYaml(this.paths.goalPath(id));
1245
- })
1246
- );
1247
- const goals = results.filter(
1410
+ const all = await this.index.readIndex();
1411
+ const goals = all.filter(
1248
1412
  (goal) => goal !== null && (!filter?.status || goal.status === filter.status)
1249
1413
  );
1250
1414
  return goals.sort((a, b) => {
@@ -1259,7 +1423,13 @@ var GoalStore = class {
1259
1423
  return readYaml(this.paths.goalPath(id));
1260
1424
  }
1261
1425
  async save(goal) {
1426
+ await ensureDir(this.paths.goalsDir);
1262
1427
  await writeYaml(this.paths.goalPath(goal.id), goal);
1428
+ await this.index.updateIndex((idx) => {
1429
+ const filtered = idx.filter((g) => g.id !== goal.id);
1430
+ filtered.push(goal);
1431
+ return filtered;
1432
+ });
1263
1433
  }
1264
1434
  async delete(id) {
1265
1435
  try {
@@ -1267,6 +1437,7 @@ var GoalStore = class {
1267
1437
  } catch (err) {
1268
1438
  if (err.code !== "ENOENT") throw err;
1269
1439
  }
1440
+ await this.index.updateIndex((idx) => idx.filter((g) => g.id !== id));
1270
1441
  }
1271
1442
  };
1272
1443
  var TeamStore = class {
@@ -1703,12 +1874,11 @@ var TeamService = class {
1703
1874
  // src/container.ts
1704
1875
  async function buildLightContainer(context) {
1705
1876
  const paths = new Paths(context.projectRoot);
1706
- await paths.requireInit();
1707
1877
  const configStore = new ConfigStore(paths);
1708
1878
  const globalConfigStore = new GlobalConfigStore();
1709
- const [config, globalConfig] = await Promise.all([
1710
- configStore.read(),
1711
- globalConfigStore.read()
1879
+ const [, config] = await Promise.all([
1880
+ paths.requireInit(),
1881
+ configStore.read()
1712
1882
  ]);
1713
1883
  const taskStore = new TaskStore(paths);
1714
1884
  const agentStore = new AgentStore(paths);
@@ -1735,7 +1905,7 @@ async function buildLightContainer(context) {
1735
1905
  stateStore,
1736
1906
  configStore,
1737
1907
  globalConfigStore,
1738
- globalConfig,
1908
+ globalConfig: DEFAULT_GLOBAL_CONFIG,
1739
1909
  contextStore,
1740
1910
  messageStore,
1741
1911
  goalStore,
@@ -1751,6 +1921,8 @@ async function buildLightContainer(context) {
1751
1921
  }
1752
1922
  async function buildFullContainer(context) {
1753
1923
  const light = await buildLightContainer(context);
1924
+ const globalConfig = await light.globalConfigStore.read();
1925
+ light.globalConfig = globalConfig;
1754
1926
  const [
1755
1927
  { ProcessManager },
1756
1928
  { AdapterRegistry: AdapterRegistry2 },
@@ -1766,14 +1938,14 @@ async function buildFullContainer(context) {
1766
1938
  ] = await Promise.all([
1767
1939
  import('./process-manager-A36Y7LHP.js'),
1768
1940
  import('./registry-JXXRLJ5J.js'),
1769
- import('./claude-WUJU5KIE.js'),
1770
- import('./codex-NYJWEPRQ.js'),
1771
- import('./cursor-3YHVD4NP.js'),
1772
- import('./shell-NJNW3O6K.js'),
1773
- import('./opencode-FAMPSA6X.js'),
1774
- import('./workspace-manager-2SFPKPLZ.js'),
1941
+ import('./claude-4R6L6BWY.js'),
1942
+ import('./codex-IMOW5ZUZ.js'),
1943
+ import('./cursor-NHV7X3WG.js'),
1944
+ import('./shell-UXEJRK3D.js'),
1945
+ import('./opencode-ULT6DYCT.js'),
1946
+ import('./workspace-manager-ABXFBL2A.js'),
1775
1947
  import('./template-engine-5ZKVJMYA.js'),
1776
- import('./orchestrator-X2CWGFCL.js'),
1948
+ import('./orchestrator-QFNYZ6AH.js'),
1777
1949
  import('./doctor-service-F2SXDWHS.js')
1778
1950
  ]);
1779
1951
  const processManager = new ProcessManager();