@code-yeongyu/senpi 2026.7.9-2 → 2026.7.9

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 (207) hide show
  1. package/CHANGELOG.md +1 -25
  2. package/README.md +1 -1
  3. package/dist/cli/args.js +3 -3
  4. package/dist/cli/args.js.map +1 -1
  5. package/dist/cli/config-selector.d.ts +2 -4
  6. package/dist/cli/config-selector.d.ts.map +1 -1
  7. package/dist/cli/config-selector.js +1 -1
  8. package/dist/cli/config-selector.js.map +1 -1
  9. package/dist/core/agent-session.d.ts +3 -18
  10. package/dist/core/agent-session.d.ts.map +1 -1
  11. package/dist/core/agent-session.js +36 -153
  12. package/dist/core/agent-session.js.map +1 -1
  13. package/dist/core/compaction/compaction.d.ts +2 -1
  14. package/dist/core/compaction/compaction.d.ts.map +1 -1
  15. package/dist/core/compaction/compaction.js +79 -54
  16. package/dist/core/compaction/compaction.js.map +1 -1
  17. package/dist/core/extensions/builtin/goal/continuation.js +1 -1
  18. package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
  19. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  20. package/dist/core/extensions/builtin/goal/index.js +0 -1
  21. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  22. package/dist/core/extensions/builtin/import-repro.d.ts.map +1 -1
  23. package/dist/core/extensions/builtin/import-repro.js +6 -100
  24. package/dist/core/extensions/builtin/import-repro.js.map +1 -1
  25. package/dist/core/extensions/builtin/mcp/connection.d.ts +0 -1
  26. package/dist/core/extensions/builtin/mcp/connection.d.ts.map +1 -1
  27. package/dist/core/extensions/builtin/mcp/connection.js +0 -15
  28. package/dist/core/extensions/builtin/mcp/connection.js.map +1 -1
  29. package/dist/core/extensions/builtin/mcp/service.d.ts.map +1 -1
  30. package/dist/core/extensions/builtin/mcp/service.js +1 -3
  31. package/dist/core/extensions/builtin/mcp/service.js.map +1 -1
  32. package/dist/core/extensions/index.d.ts +1 -1
  33. package/dist/core/extensions/index.d.ts.map +1 -1
  34. package/dist/core/extensions/index.js.map +1 -1
  35. package/dist/core/extensions/runner.d.ts +3 -4
  36. package/dist/core/extensions/runner.d.ts.map +1 -1
  37. package/dist/core/extensions/runner.js +24 -30
  38. package/dist/core/extensions/runner.js.map +1 -1
  39. package/dist/core/extensions/types.d.ts +3 -23
  40. package/dist/core/extensions/types.d.ts.map +1 -1
  41. package/dist/core/extensions/types.js.map +1 -1
  42. package/dist/core/model-registry.d.ts +0 -3
  43. package/dist/core/model-registry.d.ts.map +1 -1
  44. package/dist/core/model-registry.js +3 -20
  45. package/dist/core/model-registry.js.map +1 -1
  46. package/dist/core/package-manager.d.ts +1 -4
  47. package/dist/core/package-manager.d.ts.map +1 -1
  48. package/dist/core/package-manager.js +26 -68
  49. package/dist/core/package-manager.js.map +1 -1
  50. package/dist/core/resource-loader.d.ts +2 -2
  51. package/dist/core/resource-loader.d.ts.map +1 -1
  52. package/dist/core/resource-loader.js +7 -6
  53. package/dist/core/resource-loader.js.map +1 -1
  54. package/dist/core/sdk.d.ts +1 -1
  55. package/dist/core/sdk.d.ts.map +1 -1
  56. package/dist/core/sdk.js +2 -9
  57. package/dist/core/sdk.js.map +1 -1
  58. package/dist/core/session-manager.d.ts.map +1 -1
  59. package/dist/core/session-manager.js +2 -11
  60. package/dist/core/session-manager.js.map +1 -1
  61. package/dist/core/settings-manager.d.ts +0 -5
  62. package/dist/core/settings-manager.d.ts.map +1 -1
  63. package/dist/core/settings-manager.js +0 -8
  64. package/dist/core/settings-manager.js.map +1 -1
  65. package/dist/core/slash-commands.d.ts +0 -1
  66. package/dist/core/slash-commands.d.ts.map +1 -1
  67. package/dist/core/slash-commands.js +3 -3
  68. package/dist/core/slash-commands.js.map +1 -1
  69. package/dist/index.d.ts +1 -1
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js.map +1 -1
  72. package/dist/main.d.ts +2 -2
  73. package/dist/main.d.ts.map +1 -1
  74. package/dist/main.js +0 -1
  75. package/dist/main.js.map +1 -1
  76. package/dist/modes/interactive/components/config-selector.d.ts +3 -34
  77. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  78. package/dist/modes/interactive/components/config-selector.js +24 -272
  79. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  80. package/dist/modes/interactive/components/footer.d.ts +0 -4
  81. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  82. package/dist/modes/interactive/components/footer.js +2 -5
  83. package/dist/modes/interactive/components/footer.js.map +1 -1
  84. package/dist/modes/interactive/components/oauth-selector.d.ts +1 -3
  85. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  86. package/dist/modes/interactive/components/oauth-selector.js +6 -16
  87. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  88. package/dist/modes/interactive/components/settings-selector.d.ts +0 -2
  89. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  90. package/dist/modes/interactive/components/settings-selector.js +0 -10
  91. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  92. package/dist/modes/interactive/interactive-mode.d.ts +0 -10
  93. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  94. package/dist/modes/interactive/interactive-mode.js +37 -261
  95. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  96. package/dist/modes/print-mode.js +1 -1
  97. package/dist/modes/print-mode.js.map +1 -1
  98. package/dist/modes/rpc/rpc-client.d.ts +6 -6
  99. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  100. package/dist/modes/rpc/rpc-client.js +3 -3
  101. package/dist/modes/rpc/rpc-client.js.map +1 -1
  102. package/dist/package-manager-cli.d.ts +2 -2
  103. package/dist/package-manager-cli.d.ts.map +1 -1
  104. package/dist/package-manager-cli.js +17 -64
  105. package/dist/package-manager-cli.js.map +1 -1
  106. package/dist/utils/clipboard-image.js +1 -1
  107. package/dist/utils/clipboard-image.js.map +1 -1
  108. package/docs/extensions.md +9 -33
  109. package/docs/models.md +4 -4
  110. package/docs/packages.md +10 -7
  111. package/docs/rpc.md +3 -13
  112. package/docs/sdk.md +0 -22
  113. package/docs/settings.md +0 -1
  114. package/docs/usage.md +1 -1
  115. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  116. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  117. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  118. package/examples/extensions/gondolin/package-lock.json +2 -2
  119. package/examples/extensions/gondolin/package.json +1 -1
  120. package/examples/extensions/reload-runtime.ts +2 -2
  121. package/examples/extensions/sandbox/package-lock.json +2 -2
  122. package/examples/extensions/sandbox/package.json +1 -1
  123. package/examples/extensions/with-deps/package-lock.json +2 -2
  124. package/examples/extensions/with-deps/package.json +1 -1
  125. package/examples/sdk/README.md +1 -1
  126. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  127. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  128. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +2 -37
  129. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  130. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl-repo.d.ts.map +1 -1
  131. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl-repo.js +0 -2
  132. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl-repo.js.map +1 -1
  133. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl-storage.d.ts +0 -1
  134. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl-storage.d.ts.map +1 -1
  135. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl-storage.js +0 -7
  136. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl-storage.js.map +1 -1
  137. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.d.ts +4 -18
  138. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.d.ts.map +1 -1
  139. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.js +37 -72
  140. package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/session.js.map +1 -1
  141. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts +0 -2
  142. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts.map +1 -1
  143. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js.map +1 -1
  144. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts +0 -2
  145. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts.map +1 -1
  146. package/node_modules/@earendil-works/pi-agent-core/dist/index.js +0 -2
  147. package/node_modules/@earendil-works/pi-agent-core/dist/index.js.map +1 -1
  148. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  149. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  150. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +1 -2
  151. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  152. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +1 -1
  153. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  154. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.d.ts.map +1 -1
  155. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js +1 -4
  156. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js.map +1 -1
  157. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +195 -446
  158. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  159. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.d.ts +0 -84
  160. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.d.ts.map +1 -1
  161. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.js +0 -72
  162. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.js.map +1 -1
  163. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js +4 -4
  164. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js.map +1 -1
  165. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.d.ts +0 -63
  166. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.d.ts.map +1 -1
  167. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.js +0 -54
  168. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.js.map +1 -1
  169. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.d.ts +0 -84
  170. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.d.ts.map +1 -1
  171. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.js +0 -72
  172. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.js.map +1 -1
  173. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts +63 -138
  174. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts.map +1 -1
  175. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js +76 -136
  176. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js.map +1 -1
  177. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts +0 -77
  178. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
  179. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js +0 -71
  180. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  181. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-ams.models.d.ts +44 -0
  182. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-ams.models.d.ts.map +1 -1
  183. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-ams.models.js +45 -9
  184. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -1
  185. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-cn.models.d.ts +44 -0
  186. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-cn.models.d.ts.map +1 -1
  187. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-cn.models.js +45 -9
  188. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -1
  189. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-sgp.models.d.ts +44 -0
  190. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-sgp.models.d.ts.map +1 -1
  191. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-sgp.models.js +45 -9
  192. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -1
  193. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
  194. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +0 -3
  195. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  196. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  197. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  198. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
  199. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +1 -22
  200. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
  201. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  202. package/npm-shrinkwrap.json +14 -14
  203. package/package.json +6 -6
  204. package/dist/core/cache-stats.d.ts +0 -49
  205. package/dist/core/cache-stats.d.ts.map +0 -1
  206. package/dist/core/cache-stats.js +0 -101
  207. package/dist/core/cache-stats.js.map +0 -1
@@ -5,11 +5,9 @@ import { homedir } from "node:os";
5
5
  import { basename, dirname, join, relative } from "node:path";
6
6
  import { Container, getKeybindings, Input, matchesKey, Spacer, truncateToWidth, visibleWidth, } from "@earendil-works/pi-tui";
7
7
  import { CONFIG_DIR_NAME } from "../../../config.js";
8
- import { canonicalizePath, isLocalPath, resolvePath } from "../../../utils/paths.js";
9
8
  import { theme } from "../theme/theme.js";
10
9
  import { DynamicBorder } from "./dynamic-border.js";
11
- import { keyHint, rawKeyHint } from "./keybinding-hints.js";
12
- const RESOURCE_TYPES = ["extensions", "skills", "prompts", "themes"];
10
+ import { rawKeyHint } from "./keybinding-hints.js";
13
11
  const RESOURCE_TYPE_LABELS = {
14
12
  extensions: "Extensions",
15
13
  skills: "Skills",
@@ -123,27 +121,17 @@ function buildGroups(resolved, agentDir) {
123
121
  return groups;
124
122
  }
125
123
  class ConfigSelectorHeader {
126
- constructor(writeScope, projectModeAvailable) {
127
- this.writeScope = writeScope;
128
- this.projectModeAvailable = projectModeAvailable;
129
- }
130
- setWriteScope(writeScope) {
131
- this.writeScope = writeScope;
132
- }
133
124
  invalidate() { }
134
125
  render(width) {
135
- const title = theme.bold(this.writeScope === "project" ? "Project Local Resources" : "Global Resources");
126
+ const title = theme.bold("Resource Configuration");
136
127
  const sep = theme.fg("muted", " · ");
137
- const switchHint = this.projectModeAvailable ? keyHint("tui.input.tab", "switch mode") + sep : "";
138
- const actionHint = this.writeScope === "project" ? rawKeyHint("space", "cycle inherit/+/-") : rawKeyHint("space", "toggle");
139
- const hint = switchHint + actionHint + sep + rawKeyHint("esc", "close");
140
- const spacing = Math.max(1, width - visibleWidth(title) - visibleWidth(hint));
141
- const scopeHint = this.writeScope === "project"
142
- ? theme.fg("muted", `${CONFIG_DIR_NAME}/settings.json · inherited global resources are dimmed`)
143
- : theme.fg("muted", `~/${CONFIG_DIR_NAME}/agent/settings.json`);
128
+ const hint = rawKeyHint("space", "toggle") + sep + rawKeyHint("esc", "close");
129
+ const hintWidth = visibleWidth(hint);
130
+ const titleWidth = visibleWidth(title);
131
+ const spacing = Math.max(1, width - titleWidth - hintWidth);
144
132
  return [
145
133
  truncateToWidth(`${title}${" ".repeat(spacing)}${hint}`, width, ""),
146
- truncateToWidth(scopeHint, width, ""),
134
+ theme.fg("muted", "Type to filter resources"),
147
135
  ];
148
136
  }
149
137
  }
@@ -155,17 +143,15 @@ class ResourceList {
155
143
  this._focused = value;
156
144
  this.searchInput.focused = value;
157
145
  }
158
- constructor(groupsByScope, settingsManager, cwd, agentDir, terminalHeight, writeScope = "global") {
146
+ constructor(groups, settingsManager, cwd, agentDir, terminalHeight) {
159
147
  this.flatItems = [];
160
148
  this.filteredItems = [];
161
149
  this.selectedIndex = 0;
162
150
  this._focused = false;
163
- this.groupsByScope = groupsByScope;
151
+ this.groups = groups;
164
152
  this.settingsManager = settingsManager;
165
153
  this.cwd = cwd;
166
154
  this.agentDir = agentDir;
167
- this.writeScope = writeScope;
168
- this.inheritedEnabledByKey = this.buildInheritedEnabledMap(groupsByScope.global);
169
155
  this.searchInput = new Input();
170
156
  // 8 lines of chrome: top spacer + top border + spacer + header (2 lines) + spacer + bottom spacer + bottom border
171
157
  const chrome = 8;
@@ -173,25 +159,6 @@ class ResourceList {
173
159
  this.buildFlatList();
174
160
  this.filteredItems = [...this.flatItems];
175
161
  }
176
- setWriteScope(writeScope) {
177
- this.writeScope = writeScope;
178
- this.buildFlatList();
179
- this.filterItems(this.searchInput.getValue());
180
- }
181
- get groups() {
182
- return this.groupsByScope[this.writeScope];
183
- }
184
- buildInheritedEnabledMap(groups) {
185
- const result = new Map();
186
- for (const group of groups) {
187
- for (const subgroup of group.subgroups) {
188
- for (const item of subgroup.items) {
189
- result.set(this.getResourceItemKey(item), item.enabled);
190
- }
191
- }
192
- }
193
- return result;
194
- }
195
162
  buildFlatList() {
196
163
  this.flatItems = [];
197
164
  for (const group of this.groups) {
@@ -298,25 +265,21 @@ class ResourceList {
298
265
  const isSelected = i === this.selectedIndex;
299
266
  if (entry.type === "group") {
300
267
  // Main group header (no cursor)
301
- const inherited = this.writeScope === "project" && entry.group.scope === "user";
302
- const label = theme.bold(`${entry.group.label}${inherited ? " · inherited global" : ""}`);
303
- const groupLine = theme.fg(inherited ? "dim" : "accent", label);
268
+ const groupLine = theme.fg("accent", theme.bold(entry.group.label));
304
269
  lines.push(truncateToWidth(` ${groupLine}`, width, ""));
305
270
  }
306
271
  else if (entry.type === "subgroup") {
307
272
  // Subgroup header (indented, no cursor)
308
- const color = this.writeScope === "project" && entry.group.scope === "user" ? "dim" : "muted";
309
- const subgroupLine = theme.fg(color, entry.subgroup.label);
273
+ const subgroupLine = theme.fg("muted", entry.subgroup.label);
310
274
  lines.push(truncateToWidth(` ${subgroupLine}`, width, ""));
311
275
  }
312
276
  else {
313
277
  // Resource item (cursor only on items)
314
278
  const item = entry.item;
315
279
  const cursor = isSelected ? "> " : " ";
316
- const dimmed = this.isDimmedItem(item);
317
- const nameText = isSelected && !dimmed ? theme.bold(item.displayName) : item.displayName;
318
- const name = dimmed ? theme.fg("dim", nameText) : nameText;
319
- lines.push(truncateToWidth(`${cursor} ${this.renderCheckbox(item)} ${name}${this.getItemSuffix(item)}`, width, "..."));
280
+ const checkbox = item.enabled ? theme.fg("success", "[x]") : theme.fg("dim", "[ ]");
281
+ const name = isSelected ? theme.bold(item.displayName) : item.displayName;
282
+ lines.push(truncateToWidth(`${cursor} ${checkbox} ${name}`, width, "..."));
320
283
  }
321
284
  }
322
285
  // Scroll indicator
@@ -367,18 +330,13 @@ class ResourceList {
367
330
  this.onExit?.();
368
331
  return;
369
332
  }
370
- if (kb.matches(data, "tui.input.tab")) {
371
- this.onSwitchMode?.();
372
- return;
373
- }
374
333
  if (data === " " || kb.matches(data, "tui.select.confirm")) {
375
334
  const entry = this.filteredItems[this.selectedIndex];
376
- if (entry?.type === "item" && (this.writeScope === "project" || this.getItemScope(entry.item) === "user")) {
377
- const newEnabled = this.toggleResource(entry.item);
378
- if (newEnabled !== undefined) {
379
- this.updateItem(entry.item, newEnabled);
380
- this.onToggle?.(entry.item, newEnabled);
381
- }
335
+ if (entry?.type === "item") {
336
+ const newEnabled = !entry.item.enabled;
337
+ this.toggleResource(entry.item, newEnabled);
338
+ this.updateItem(entry.item, newEnabled);
339
+ this.onToggle?.(entry.item, newEnabled);
382
340
  }
383
341
  return;
384
342
  }
@@ -386,21 +344,13 @@ class ResourceList {
386
344
  this.searchInput.handleInput(data);
387
345
  this.filterItems(this.searchInput.getValue());
388
346
  }
389
- toggleResource(item) {
390
- if (this.writeScope === "project") {
391
- const state = this.getNextOverrideState(item);
392
- if (!this.setProjectResourceOverride(item, state))
393
- return undefined;
394
- return state === "inherit" ? this.getInheritedEnabled(item) : state === "load";
395
- }
396
- const enabled = !item.enabled;
347
+ toggleResource(item, enabled) {
397
348
  if (item.metadata.origin === "top-level") {
398
349
  this.toggleTopLevelResource(item, enabled);
399
350
  }
400
351
  else {
401
352
  this.togglePackageResource(item, enabled);
402
353
  }
403
- return enabled;
404
354
  }
405
355
  toggleTopLevelResource(item, enabled) {
406
356
  const scope = item.metadata.scope;
@@ -498,188 +448,6 @@ class ResourceList {
498
448
  this.settingsManager.setPackages(packages);
499
449
  }
500
450
  }
501
- renderCheckbox(item) {
502
- if (this.writeScope === "project") {
503
- const state = this.getProjectOverrideState(item);
504
- if (state === "load")
505
- return theme.fg("success", "[+]");
506
- if (state === "unload")
507
- return theme.fg("warning", "[-]");
508
- return theme.fg("dim", item.enabled ? "[x]" : "[ ]");
509
- }
510
- return item.enabled ? theme.fg("success", "[x]") : theme.fg("dim", "[ ]");
511
- }
512
- getItemSuffix(item) {
513
- if (this.writeScope !== "project")
514
- return "";
515
- const state = this.getProjectOverrideState(item);
516
- if (state === "load")
517
- return theme.fg("muted", " project load");
518
- if (state === "unload")
519
- return theme.fg("muted", " project unload");
520
- return this.isInheritedGlobalItem(item) ? theme.fg("dim", " inherited global") : "";
521
- }
522
- isDimmedItem(item) {
523
- return (this.writeScope === "project" &&
524
- this.isInheritedGlobalItem(item) &&
525
- this.getProjectOverrideState(item) === "inherit");
526
- }
527
- setProjectResourceOverride(item, state) {
528
- return item.metadata.origin === "top-level"
529
- ? this.setProjectTopLevelOverride(item, state)
530
- : this.setProjectPackageOverride(item, state);
531
- }
532
- setProjectTopLevelOverride(item, state) {
533
- const current = (this.settingsManager.getProjectSettings()[item.resourceType] ?? []);
534
- const pattern = this.isInheritedGlobalItem(item) ? item.path : this.getResourcePatternForScope(item, "project");
535
- const patterns = this.getTopLevelOverridePatterns(item, "project");
536
- const updated = current.filter((entry) => {
537
- const target = this.getPatternEntryTarget(entry);
538
- if ((entry.startsWith("!") || entry.startsWith("+") || entry.startsWith("-")) && patterns.has(target))
539
- return false;
540
- return !(state === "inherit" && this.isInheritedGlobalItem(item) && target === pattern);
541
- });
542
- if (state !== "inherit") {
543
- if (this.isInheritedGlobalItem(item) && !updated.includes(pattern))
544
- updated.push(pattern);
545
- updated.push(`${state === "load" ? "+" : "-"}${pattern}`);
546
- }
547
- this.setProjectTopLevelPaths(item.resourceType, updated);
548
- return true;
549
- }
550
- setProjectTopLevelPaths(key, paths) {
551
- if (key === "extensions")
552
- this.settingsManager.setProjectExtensionPaths(paths);
553
- else if (key === "skills")
554
- this.settingsManager.setProjectSkillPaths(paths);
555
- else if (key === "prompts")
556
- this.settingsManager.setProjectPromptTemplatePaths(paths);
557
- else
558
- this.settingsManager.setProjectThemePaths(paths);
559
- }
560
- setProjectPackageOverride(item, state) {
561
- const packages = [...(this.settingsManager.getProjectSettings().packages ?? [])];
562
- let pkgIndex = packages.findIndex((pkg) => this.packageSourceStringMatches(item.metadata.source, this.getItemScope(item), typeof pkg === "string" ? pkg : pkg.source, "project"));
563
- if (pkgIndex === -1) {
564
- if (state === "inherit")
565
- return false;
566
- packages.push(this.createPackageOverrideSource(item));
567
- pkgIndex = packages.length - 1;
568
- }
569
- let pkg = packages[pkgIndex];
570
- if (pkg === undefined)
571
- return false;
572
- if (typeof pkg === "string") {
573
- pkg = { source: pkg };
574
- packages[pkgIndex] = pkg;
575
- }
576
- const pattern = this.getPackageResourcePattern(item);
577
- const updated = (pkg[item.resourceType] ?? []).filter((entry) => this.getPatternEntryTarget(entry) !== pattern);
578
- if (state !== "inherit")
579
- updated.push(`${state === "load" ? "+" : "-"}${pattern}`);
580
- pkg[item.resourceType] = updated.length > 0 ? updated : undefined;
581
- if (!RESOURCE_TYPES.some((key) => pkg[key] !== undefined)) {
582
- if (pkg.autoload === false)
583
- packages.splice(pkgIndex, 1);
584
- else
585
- packages[pkgIndex] = pkg.source;
586
- }
587
- this.settingsManager.setProjectPackages(packages);
588
- return true;
589
- }
590
- getNextOverrideState(item) {
591
- const state = this.getProjectOverrideState(item);
592
- const inheritedEnabled = this.getInheritedEnabled(item);
593
- if (state === "inherit")
594
- return inheritedEnabled ? "unload" : "load";
595
- if (state === "unload")
596
- return inheritedEnabled ? "load" : "inherit";
597
- return inheritedEnabled ? "inherit" : "unload";
598
- }
599
- getProjectOverrideState(item) {
600
- if (this.writeScope !== "project")
601
- return "inherit";
602
- if (item.metadata.origin === "top-level") {
603
- return this.getOverrideStateFromEntries((this.settingsManager.getProjectSettings()[item.resourceType] ?? []), this.getTopLevelOverridePatterns(item, "project"), false);
604
- }
605
- const pkg = this.findMatchingPackageSource(item, "project");
606
- if (typeof pkg !== "object")
607
- return "inherit";
608
- const entries = pkg[item.resourceType];
609
- if (entries === undefined)
610
- return "inherit";
611
- return this.getOverrideStateFromEntries(entries, new Set([this.getPackageResourcePattern(item)]), pkg.autoload !== false);
612
- }
613
- getOverrideStateFromEntries(entries, patterns, emptyArrayIsUnload) {
614
- if (entries.length === 0 && emptyArrayIsUnload)
615
- return "unload";
616
- let state = "inherit";
617
- for (const entry of entries) {
618
- if (!patterns.has(this.getPatternEntryTarget(entry)))
619
- continue;
620
- if (entry.startsWith("!") || entry.startsWith("-"))
621
- state = "unload";
622
- else
623
- state = "load";
624
- }
625
- return state;
626
- }
627
- getInheritedEnabled(item) {
628
- return (this.inheritedEnabledByKey.get(this.getResourceItemKey(item)) ??
629
- (this.getItemScope(item) === "user" ? item.enabled : true));
630
- }
631
- isInheritedGlobalItem(item) {
632
- return this.getItemScope(item) === "user" || this.inheritedEnabledByKey.has(this.getResourceItemKey(item));
633
- }
634
- getTopLevelOverridePatterns(item, scope) {
635
- const baseDir = this.getTopLevelBaseDir(scope);
636
- const patterns = new Set([
637
- this.getResourcePatternForScope(item, scope),
638
- item.path,
639
- relative(baseDir, item.path),
640
- ]);
641
- if (item.metadata.baseDir)
642
- patterns.add(relative(item.metadata.baseDir, item.path));
643
- return patterns;
644
- }
645
- getResourcePatternForScope(item, scope) {
646
- const sourceScope = this.getItemScope(item);
647
- if (scope !== sourceScope)
648
- return item.path;
649
- const baseDir = item.metadata.baseDir ?? this.getTopLevelBaseDir(sourceScope);
650
- return relative(baseDir, item.path);
651
- }
652
- createPackageOverrideSource(item) {
653
- const source = item.metadata.source;
654
- if (!isLocalPath(source))
655
- return { source, autoload: false };
656
- const sourcePath = resolvePath(source, this.getTopLevelBaseDir(this.getItemScope(item)), { trim: true });
657
- return { source: relative(this.getTopLevelBaseDir("project"), sourcePath) || ".", autoload: false };
658
- }
659
- packageSourceStringMatches(leftSource, leftScope, rightSource, rightScope) {
660
- if (leftSource === rightSource)
661
- return true;
662
- if (!isLocalPath(leftSource) || !isLocalPath(rightSource))
663
- return false;
664
- const left = resolvePath(leftSource, this.getTopLevelBaseDir(leftScope), { trim: true });
665
- const right = resolvePath(rightSource, this.getTopLevelBaseDir(rightScope), { trim: true });
666
- return left === right;
667
- }
668
- findMatchingPackageSource(item, targetScope) {
669
- const settings = targetScope === "project"
670
- ? this.settingsManager.getProjectSettings()
671
- : this.settingsManager.getGlobalSettings();
672
- return (settings.packages ?? []).find((pkg) => this.packageSourceStringMatches(item.metadata.source, this.getItemScope(item), typeof pkg === "string" ? pkg : pkg.source, targetScope));
673
- }
674
- getPatternEntryTarget(entry) {
675
- return entry.startsWith("!") || entry.startsWith("+") || entry.startsWith("-") ? entry.slice(1) : entry;
676
- }
677
- getResourceItemKey(item) {
678
- return `${item.resourceType}:${canonicalizePath(item.path)}`;
679
- }
680
- getItemScope(item) {
681
- return item.metadata.scope === "project" ? "project" : "user";
682
- }
683
451
  getTopLevelBaseDir(scope) {
684
452
  return scope === "project" ? join(this.cwd, CONFIG_DIR_NAME) : this.agentDir;
685
453
  }
@@ -701,42 +469,26 @@ export class ConfigSelectorComponent extends Container {
701
469
  this._focused = value;
702
470
  this.resourceList.focused = value;
703
471
  }
704
- constructor(resolvedPaths, settingsManager, cwd, agentDir, onClose, onExit, requestRender, terminalHeight, writeScope = "global", projectModeAvailable = true) {
472
+ constructor(resolvedPaths, settingsManager, cwd, agentDir, onClose, onExit, requestRender, terminalHeight) {
705
473
  super();
706
474
  this._focused = false;
707
- this.writeScope = writeScope;
708
- const groupsByScope = {
709
- global: buildGroups(resolvedPaths.global, agentDir),
710
- project: buildGroups(resolvedPaths.project, agentDir),
711
- };
475
+ const groups = buildGroups(resolvedPaths, agentDir);
712
476
  // Add header
713
477
  this.addChild(new Spacer(1));
714
478
  this.addChild(new DynamicBorder());
715
479
  this.addChild(new Spacer(1));
716
- this.header = new ConfigSelectorHeader(this.writeScope, projectModeAvailable);
717
- this.addChild(this.header);
480
+ this.addChild(new ConfigSelectorHeader());
718
481
  this.addChild(new Spacer(1));
719
482
  // Resource list
720
- this.resourceList = new ResourceList(groupsByScope, settingsManager, cwd, agentDir, terminalHeight, this.writeScope);
483
+ this.resourceList = new ResourceList(groups, settingsManager, cwd, agentDir, terminalHeight);
721
484
  this.resourceList.onCancel = onClose;
722
485
  this.resourceList.onExit = onExit;
723
486
  this.resourceList.onToggle = () => requestRender();
724
- if (projectModeAvailable) {
725
- this.resourceList.onSwitchMode = () => {
726
- this.switchWriteScope();
727
- requestRender();
728
- };
729
- }
730
487
  this.addChild(this.resourceList);
731
488
  // Bottom border
732
489
  this.addChild(new Spacer(1));
733
490
  this.addChild(new DynamicBorder());
734
491
  }
735
- switchWriteScope() {
736
- this.writeScope = this.writeScope === "global" ? "project" : "global";
737
- this.header.setWriteScope(this.writeScope);
738
- this.resourceList.setWriteScope(this.writeScope);
739
- }
740
492
  getResourceList() {
741
493
  return this.resourceList;
742
494
  }