@bastani/atomic 0.9.5-alpha.5 → 0.9.5-alpha.7

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 (216) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/builtin/cursor/package.json +2 -2
  3. package/dist/builtin/intercom/package.json +1 -1
  4. package/dist/builtin/mcp/package.json +1 -1
  5. package/dist/builtin/subagents/package.json +1 -1
  6. package/dist/builtin/web-access/package.json +1 -1
  7. package/dist/builtin/workflows/CHANGELOG.md +6 -0
  8. package/dist/builtin/workflows/package.json +1 -1
  9. package/dist/builtin/workflows/src/runs/foreground/executor-stage-control.ts +8 -0
  10. package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +2 -0
  11. package/dist/builtin/workflows/src/runs/foreground/stage-tool-execution-buffer.ts +47 -0
  12. package/dist/builtin/workflows/src/tui/stage-chat-view-pending-tools.ts +9 -0
  13. package/dist/builtin/workflows/src/tui/stage-chat-view-render-settings.ts +27 -0
  14. package/dist/builtin/workflows/src/tui/stage-chat-view-state.ts +5 -6
  15. package/dist/bun/split-loader.d.ts +2 -0
  16. package/dist/bun/split-loader.d.ts.map +1 -0
  17. package/dist/bun/split-loader.js +37 -0
  18. package/dist/bun/split-loader.js.map +1 -0
  19. package/dist/config.d.ts.map +1 -1
  20. package/dist/config.js +6 -4
  21. package/dist/config.js.map +1 -1
  22. package/dist/core/agent-session-auto-compaction.d.ts +5 -4
  23. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  24. package/dist/core/agent-session-auto-compaction.js +15 -9
  25. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  26. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  27. package/dist/core/agent-session-extension-bindings.js +1 -1
  28. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  29. package/dist/core/agent-session-methods.d.ts +1 -1
  30. package/dist/core/agent-session-methods.d.ts.map +1 -1
  31. package/dist/core/agent-session-methods.js.map +1 -1
  32. package/dist/core/builtin-packages.d.ts.map +1 -1
  33. package/dist/core/builtin-packages.js +8 -4
  34. package/dist/core/builtin-packages.js.map +1 -1
  35. package/dist/core/copilot-model-catalog.d.ts.map +1 -1
  36. package/dist/core/copilot-model-catalog.js +3 -2
  37. package/dist/core/copilot-model-catalog.js.map +1 -1
  38. package/dist/core/extensions/loader-core.d.ts.map +1 -1
  39. package/dist/core/extensions/loader-core.js +6 -0
  40. package/dist/core/extensions/loader-core.js.map +1 -1
  41. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  42. package/dist/core/extensions/loader-virtual-modules.js +8 -3
  43. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  44. package/dist/core/model-resolver-scope.d.ts +9 -0
  45. package/dist/core/model-resolver-scope.d.ts.map +1 -1
  46. package/dist/core/model-resolver-scope.js +12 -4
  47. package/dist/core/model-resolver-scope.js.map +1 -1
  48. package/dist/core/model-resolver.d.ts +3 -2
  49. package/dist/core/model-resolver.d.ts.map +1 -1
  50. package/dist/core/model-resolver.js +1 -1
  51. package/dist/core/model-resolver.js.map +1 -1
  52. package/dist/core/openai-responses-payload-sanitizer.d.ts +6 -0
  53. package/dist/core/openai-responses-payload-sanitizer.d.ts.map +1 -0
  54. package/dist/core/openai-responses-payload-sanitizer.js +59 -0
  55. package/dist/core/openai-responses-payload-sanitizer.js.map +1 -0
  56. package/dist/core/package-manager-auto-resources.d.ts +2 -2
  57. package/dist/core/package-manager-auto-resources.d.ts.map +1 -1
  58. package/dist/core/package-manager-auto-resources.js +32 -52
  59. package/dist/core/package-manager-auto-resources.js.map +1 -1
  60. package/dist/core/package-manager-resolver.d.ts.map +1 -1
  61. package/dist/core/package-manager-resolver.js +23 -14
  62. package/dist/core/package-manager-resolver.js.map +1 -1
  63. package/dist/core/package-manager-resource-collector.d.ts +3 -3
  64. package/dist/core/package-manager-resource-collector.d.ts.map +1 -1
  65. package/dist/core/package-manager-resource-collector.js +76 -73
  66. package/dist/core/package-manager-resource-collector.js.map +1 -1
  67. package/dist/core/package-manager-resource-files.d.ts +9 -8
  68. package/dist/core/package-manager-resource-files.d.ts.map +1 -1
  69. package/dist/core/package-manager-resource-files.js +92 -81
  70. package/dist/core/package-manager-resource-files.js.map +1 -1
  71. package/dist/core/prompt-templates-async.d.ts +3 -0
  72. package/dist/core/prompt-templates-async.d.ts.map +1 -0
  73. package/dist/core/prompt-templates-async.js +118 -0
  74. package/dist/core/prompt-templates-async.js.map +1 -0
  75. package/dist/core/provider-context-usage.d.ts +11 -0
  76. package/dist/core/provider-context-usage.d.ts.map +1 -0
  77. package/dist/core/provider-context-usage.js +58 -0
  78. package/dist/core/provider-context-usage.js.map +1 -0
  79. package/dist/core/resource-loader-assets.d.ts +3 -3
  80. package/dist/core/resource-loader-assets.d.ts.map +1 -1
  81. package/dist/core/resource-loader-assets.js +66 -83
  82. package/dist/core/resource-loader-assets.js.map +1 -1
  83. package/dist/core/resource-loader-core.d.ts +1 -1
  84. package/dist/core/resource-loader-core.d.ts.map +1 -1
  85. package/dist/core/resource-loader-core.js +5 -5
  86. package/dist/core/resource-loader-core.js.map +1 -1
  87. package/dist/core/resource-loader-extensions.d.ts.map +1 -1
  88. package/dist/core/resource-loader-extensions.js +4 -0
  89. package/dist/core/resource-loader-extensions.js.map +1 -1
  90. package/dist/core/resource-loader-reload.d.ts.map +1 -1
  91. package/dist/core/resource-loader-reload.js +54 -7
  92. package/dist/core/resource-loader-reload.js.map +1 -1
  93. package/dist/core/resource-loader-types.d.ts +7 -1
  94. package/dist/core/resource-loader-types.d.ts.map +1 -1
  95. package/dist/core/resource-loader-types.js.map +1 -1
  96. package/dist/core/sdk.d.ts.map +1 -1
  97. package/dist/core/sdk.js +6 -4
  98. package/dist/core/sdk.js.map +1 -1
  99. package/dist/core/settings-manager-core.d.ts.map +1 -1
  100. package/dist/core/settings-manager-core.js +3 -2
  101. package/dist/core/settings-manager-core.js.map +1 -1
  102. package/dist/core/settings-storage.d.ts.map +1 -1
  103. package/dist/core/settings-storage.js +2 -1
  104. package/dist/core/settings-storage.js.map +1 -1
  105. package/dist/core/skills-async.d.ts +3 -0
  106. package/dist/core/skills-async.d.ts.map +1 -0
  107. package/dist/core/skills-async.js +269 -0
  108. package/dist/core/skills-async.js.map +1 -0
  109. package/dist/core/trust-manager.d.ts +9 -0
  110. package/dist/core/trust-manager.d.ts.map +1 -1
  111. package/dist/core/trust-manager.js +44 -2
  112. package/dist/core/trust-manager.js.map +1 -1
  113. package/dist/index.d.ts +1 -1
  114. package/dist/index.d.ts.map +1 -1
  115. package/dist/index.js +1 -1
  116. package/dist/index.js.map +1 -1
  117. package/dist/main-deferred-startup.d.ts +21 -0
  118. package/dist/main-deferred-startup.d.ts.map +1 -0
  119. package/dist/main-deferred-startup.js +23 -0
  120. package/dist/main-deferred-startup.js.map +1 -0
  121. package/dist/main.d.ts.map +1 -1
  122. package/dist/main.js +28 -26
  123. package/dist/main.js.map +1 -1
  124. package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
  125. package/dist/modes/interactive/interactive-agent-events.js +10 -1
  126. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  127. package/dist/modes/interactive/interactive-deferred-startup.d.ts +8 -1
  128. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
  129. package/dist/modes/interactive/interactive-deferred-startup.js +58 -11
  130. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  131. package/dist/modes/interactive/interactive-editor-actions.d.ts.map +1 -1
  132. package/dist/modes/interactive/interactive-editor-actions.js +13 -13
  133. package/dist/modes/interactive/interactive-editor-actions.js.map +1 -1
  134. package/dist/modes/interactive/interactive-extension-runtime.d.ts.map +1 -1
  135. package/dist/modes/interactive/interactive-extension-runtime.js +16 -0
  136. package/dist/modes/interactive/interactive-extension-runtime.js.map +1 -1
  137. package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
  138. package/dist/modes/interactive/interactive-input-handling.js +48 -0
  139. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  140. package/dist/modes/interactive/interactive-mode-base.d.ts +5 -0
  141. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  142. package/dist/modes/interactive/interactive-mode-base.js +5 -0
  143. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  144. package/dist/modes/interactive/interactive-mode-deps.d.ts +2 -2
  145. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  146. package/dist/modes/interactive/interactive-mode-deps.js +2 -2
  147. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  148. package/dist/modes/interactive/interactive-mode-surface.d.ts +18 -6
  149. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  150. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  151. package/dist/modes/interactive/interactive-mode-types.d.ts +5 -1
  152. package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
  153. package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
  154. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  155. package/dist/modes/interactive/interactive-model-routing.js +3 -3
  156. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  157. package/dist/modes/interactive/interactive-onboarding.d.ts.map +1 -1
  158. package/dist/modes/interactive/interactive-onboarding.js +1 -0
  159. package/dist/modes/interactive/interactive-onboarding.js.map +1 -1
  160. package/dist/modes/interactive/interactive-process-lifecycle.d.ts.map +1 -1
  161. package/dist/modes/interactive/interactive-process-lifecycle.js +43 -6
  162. package/dist/modes/interactive/interactive-process-lifecycle.js.map +1 -1
  163. package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
  164. package/dist/modes/interactive/interactive-render-chat.js +57 -0
  165. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  166. package/dist/modes/interactive/interactive-resource-disclosure.d.ts.map +1 -1
  167. package/dist/modes/interactive/interactive-resource-disclosure.js +3 -2
  168. package/dist/modes/interactive/interactive-resource-disclosure.js.map +1 -1
  169. package/dist/modes/interactive/interactive-resource-rendering.d.ts.map +1 -1
  170. package/dist/modes/interactive/interactive-resource-rendering.js +10 -8
  171. package/dist/modes/interactive/interactive-resource-rendering.js.map +1 -1
  172. package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
  173. package/dist/modes/interactive/interactive-session-routing.js +2 -2
  174. package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
  175. package/dist/modes/interactive/interactive-session-runtime.d.ts.map +1 -1
  176. package/dist/modes/interactive/interactive-session-runtime.js +1 -1
  177. package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
  178. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  179. package/dist/modes/interactive/interactive-startup.js +59 -52
  180. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  181. package/dist/modes/interactive/theme/theme-loading.d.ts +1 -0
  182. package/dist/modes/interactive/theme/theme-loading.d.ts.map +1 -1
  183. package/dist/modes/interactive/theme/theme-loading.js +3 -0
  184. package/dist/modes/interactive/theme/theme-loading.js.map +1 -1
  185. package/dist/modes/interactive/theme/theme.d.ts +1 -1
  186. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  187. package/dist/modes/interactive/theme/theme.js +1 -1
  188. package/dist/modes/interactive/theme/theme.js.map +1 -1
  189. package/dist/utils/child-process.d.ts +8 -1
  190. package/dist/utils/child-process.d.ts.map +1 -1
  191. package/dist/utils/child-process.js +39 -6
  192. package/dist/utils/child-process.js.map +1 -1
  193. package/dist/utils/event-loop.d.ts +7 -0
  194. package/dist/utils/event-loop.d.ts.map +1 -0
  195. package/dist/utils/event-loop.js +14 -0
  196. package/dist/utils/event-loop.js.map +1 -0
  197. package/dist/utils/json.d.ts +4 -0
  198. package/dist/utils/json.d.ts.map +1 -1
  199. package/dist/utils/json.js +8 -0
  200. package/dist/utils/json.js.map +1 -1
  201. package/dist/utils/module-require.d.ts +11 -0
  202. package/dist/utils/module-require.d.ts.map +1 -1
  203. package/dist/utils/module-require.js +14 -1
  204. package/dist/utils/module-require.js.map +1 -1
  205. package/dist/utils/split-launcher.d.ts +38 -0
  206. package/dist/utils/split-launcher.d.ts.map +1 -0
  207. package/dist/utils/split-launcher.js +63 -0
  208. package/dist/utils/split-launcher.js.map +1 -0
  209. package/docs/compaction.md +3 -0
  210. package/docs/keybindings.md +2 -2
  211. package/docs/providers.md +1 -1
  212. package/docs/settings.md +5 -1
  213. package/docs/usage.md +1 -1
  214. package/docs/workflows.md +1 -1
  215. package/npm-shrinkwrap.json +23 -23
  216. package/package.json +4 -4
@@ -1,15 +1,24 @@
1
- import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
2
- import { dirname, join, relative, resolve } from "node:path";
1
+ import { access, readdir, readFile, stat } from "node:fs/promises";
2
+ import { dirname, join, relative, resolve, sep } from "node:path";
3
3
  import ignore from "ignore";
4
- import { readPiManifestFile } from "./package-manager-manifest.js";
4
+ import { yieldToEventLoopIfSlow } from "../utils/event-loop.js";
5
+ import { getManifestFromPackageJson } from "./package-manager-manifest.js";
5
6
  import { toPosixPath } from "./package-manager-resource-patterns.js";
6
7
  import { FILE_PATTERNS } from "./package-manager-types.js";
7
8
  const IGNORE_FILE_NAMES = [".gitignore", ".ignore", ".fdignore"];
9
+ const RESOURCE_DISCOVERY_YIELD_AFTER_MS = 8;
10
+ async function exists(path) {
11
+ try {
12
+ await access(path);
13
+ return true;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ }
8
19
  function prefixIgnorePattern(line, prefix) {
9
20
  const trimmed = line.trim();
10
- if (!trimmed)
11
- return null;
12
- if (trimmed.startsWith("#") && !trimmed.startsWith("\\#"))
21
+ if (!trimmed || (trimmed.startsWith("#") && !trimmed.startsWith("\\#")))
13
22
  return null;
14
23
  let pattern = line;
15
24
  let negated = false;
@@ -17,42 +26,36 @@ function prefixIgnorePattern(line, prefix) {
17
26
  negated = true;
18
27
  pattern = pattern.slice(1);
19
28
  }
20
- else if (pattern.startsWith("\\!")) {
29
+ else if (pattern.startsWith("\\!"))
21
30
  pattern = pattern.slice(1);
22
- }
23
- if (pattern.startsWith("/")) {
31
+ if (pattern.startsWith("/"))
24
32
  pattern = pattern.slice(1);
25
- }
26
33
  const prefixed = prefix ? `${prefix}${pattern}` : pattern;
27
34
  return negated ? `!${prefixed}` : prefixed;
28
35
  }
29
- function addIgnoreRules(ig, dir, rootDir) {
36
+ async function addIgnoreRules(ig, dir, rootDir) {
30
37
  const relativeDir = relative(rootDir, dir);
31
38
  const prefix = relativeDir ? `${toPosixPath(relativeDir)}/` : "";
32
39
  for (const filename of IGNORE_FILE_NAMES) {
33
- const ignorePath = join(dir, filename);
34
- if (!existsSync(ignorePath))
35
- continue;
36
40
  try {
37
- const content = readFileSync(ignorePath, "utf-8");
41
+ const content = await readFile(join(dir, filename), "utf-8");
38
42
  const patterns = content
39
43
  .split(/\r?\n/)
40
44
  .map((line) => prefixIgnorePattern(line, prefix))
41
45
  .filter((line) => Boolean(line));
42
- if (patterns.length > 0) {
46
+ if (patterns.length > 0)
43
47
  ig.add(patterns);
44
- }
45
48
  }
46
49
  catch { }
47
50
  }
48
51
  }
49
- function getEntryInfo(dir, name, isDirectory, isFileEntry, isSymlink) {
52
+ async function getEntryInfo(dir, name, isDirectory, isFileEntry, isSymlink) {
50
53
  const fullPath = join(dir, name);
51
54
  let isDir = isDirectory;
52
55
  let isFile = isFileEntry;
53
56
  if (isSymlink) {
54
57
  try {
55
- const stats = statSync(fullPath);
58
+ const stats = await stat(fullPath);
56
59
  isDir = stats.isDirectory();
57
60
  isFile = stats.isFile();
58
61
  }
@@ -62,51 +65,50 @@ function getEntryInfo(dir, name, isDirectory, isFileEntry, isSymlink) {
62
65
  }
63
66
  return { fullPath, isDir, isFile };
64
67
  }
65
- export function collectFiles(dir, filePattern, skipNodeModules = true, ignoreMatcher, rootDir) {
68
+ export async function collectFiles(dir, filePattern, skipNodeModules = true, ignoreMatcher, rootDir) {
66
69
  const files = [];
67
- if (!existsSync(dir))
70
+ if (!(await exists(dir)))
68
71
  return files;
69
72
  const root = rootDir ?? dir;
70
73
  const ig = ignoreMatcher ?? ignore();
71
- addIgnoreRules(ig, dir, root);
74
+ await addIgnoreRules(ig, dir, root);
75
+ const startedAt = Date.now();
72
76
  try {
73
- const entries = readdirSync(dir, { withFileTypes: true });
77
+ const entries = await readdir(dir, { withFileTypes: true });
74
78
  for (const entry of entries) {
75
- if (entry.name.startsWith("."))
79
+ await yieldToEventLoopIfSlow(startedAt, RESOURCE_DISCOVERY_YIELD_AFTER_MS);
80
+ if (entry.name.startsWith(".") || (skipNodeModules && entry.name === "node_modules"))
76
81
  continue;
77
- if (skipNodeModules && entry.name === "node_modules")
78
- continue;
79
- const info = getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());
82
+ const info = await getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());
80
83
  if (!info)
81
84
  continue;
82
85
  const relPath = toPosixPath(relative(root, info.fullPath));
83
86
  const ignorePath = info.isDir ? `${relPath}/` : relPath;
84
87
  if (ig.ignores(ignorePath))
85
88
  continue;
86
- if (info.isDir) {
87
- files.push(...collectFiles(info.fullPath, filePattern, skipNodeModules, ig, root));
88
- }
89
- else if (info.isFile && filePattern.test(entry.name)) {
89
+ if (info.isDir)
90
+ files.push(...await collectFiles(info.fullPath, filePattern, skipNodeModules, ig, root));
91
+ else if (info.isFile && filePattern.test(entry.name))
90
92
  files.push(info.fullPath);
91
- }
92
93
  }
93
94
  }
94
95
  catch { }
95
96
  return files;
96
97
  }
97
- function collectSkillEntries(dir, mode, ignoreMatcher, rootDir) {
98
+ async function collectSkillEntries(dir, mode, ignoreMatcher, rootDir) {
98
99
  const entries = [];
99
- if (!existsSync(dir))
100
+ if (!(await exists(dir)))
100
101
  return entries;
101
102
  const root = rootDir ?? dir;
102
103
  const ig = ignoreMatcher ?? ignore();
103
- addIgnoreRules(ig, dir, root);
104
+ await addIgnoreRules(ig, dir, root);
105
+ const startedAt = Date.now();
104
106
  try {
105
- const dirEntries = readdirSync(dir, { withFileTypes: true });
107
+ const dirEntries = await readdir(dir, { withFileTypes: true });
106
108
  for (const entry of dirEntries) {
107
109
  if (entry.name !== "SKILL.md")
108
110
  continue;
109
- const info = getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());
111
+ const info = await getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());
110
112
  if (!info)
111
113
  continue;
112
114
  const relPath = toPosixPath(relative(root, info.fullPath));
@@ -116,11 +118,10 @@ function collectSkillEntries(dir, mode, ignoreMatcher, rootDir) {
116
118
  }
117
119
  }
118
120
  for (const entry of dirEntries) {
119
- if (entry.name.startsWith("."))
120
- continue;
121
- if (entry.name === "node_modules")
121
+ await yieldToEventLoopIfSlow(startedAt, RESOURCE_DISCOVERY_YIELD_AFTER_MS);
122
+ if (entry.name.startsWith(".") || entry.name === "node_modules")
122
123
  continue;
123
- const info = getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());
124
+ const info = await getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());
124
125
  if (!info)
125
126
  continue;
126
127
  const relPath = toPosixPath(relative(root, info.fullPath));
@@ -130,19 +131,19 @@ function collectSkillEntries(dir, mode, ignoreMatcher, rootDir) {
130
131
  }
131
132
  if (!info.isDir || ig.ignores(`${relPath}/`))
132
133
  continue;
133
- entries.push(...collectSkillEntries(info.fullPath, mode, ig, root));
134
+ entries.push(...await collectSkillEntries(info.fullPath, mode, ig, root));
134
135
  }
135
136
  }
136
137
  catch { }
137
138
  return entries;
138
139
  }
139
- export function collectAutoSkillEntries(dir, mode) {
140
+ export async function collectAutoSkillEntries(dir, mode) {
140
141
  return collectSkillEntries(dir, mode);
141
142
  }
142
- function findGitRepoRoot(startDir) {
143
+ async function findGitRepoRoot(startDir) {
143
144
  let dir = resolve(startDir);
144
145
  while (true) {
145
- if (existsSync(join(dir, ".git")))
146
+ if (await exists(join(dir, ".git")))
146
147
  return dir;
147
148
  const parent = dirname(dir);
148
149
  if (parent === dir)
@@ -150,10 +151,10 @@ function findGitRepoRoot(startDir) {
150
151
  dir = parent;
151
152
  }
152
153
  }
153
- export function collectAncestorAgentsSkillDirs(startDir) {
154
+ export async function collectAncestorAgentsSkillDirs(startDir) {
154
155
  const skillDirs = [];
155
156
  const resolvedStartDir = resolve(startDir);
156
- const gitRepoRoot = findGitRepoRoot(resolvedStartDir);
157
+ const gitRepoRoot = await findGitRepoRoot(resolvedStartDir);
157
158
  let dir = resolvedStartDir;
158
159
  while (true) {
159
160
  skillDirs.push(join(dir, ".agents", "skills"));
@@ -166,18 +167,20 @@ export function collectAncestorAgentsSkillDirs(startDir) {
166
167
  }
167
168
  return skillDirs;
168
169
  }
169
- function collectFlatEntries(dir, extension) {
170
+ async function collectFlatEntries(dir, extension) {
170
171
  const entries = [];
171
- if (!existsSync(dir))
172
+ if (!(await exists(dir)))
172
173
  return entries;
173
174
  const ig = ignore();
174
- addIgnoreRules(ig, dir, dir);
175
+ await addIgnoreRules(ig, dir, dir);
176
+ const startedAt = Date.now();
175
177
  try {
176
- const dirEntries = readdirSync(dir, { withFileTypes: true });
178
+ const dirEntries = await readdir(dir, { withFileTypes: true });
177
179
  for (const entry of dirEntries) {
180
+ await yieldToEventLoopIfSlow(startedAt, RESOURCE_DISCOVERY_YIELD_AFTER_MS);
178
181
  if (entry.name.startsWith(".") || entry.name === "node_modules")
179
182
  continue;
180
- const info = getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());
183
+ const info = await getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());
181
184
  if (!info)
182
185
  continue;
183
186
  const relPath = toPosixPath(relative(dir, info.fullPath));
@@ -190,61 +193,66 @@ function collectFlatEntries(dir, extension) {
190
193
  catch { }
191
194
  return entries;
192
195
  }
193
- export function collectAutoPromptEntries(dir) {
196
+ export async function collectAutoPromptEntries(dir) {
194
197
  return collectFlatEntries(dir, ".md");
195
198
  }
196
- export function collectAutoThemeEntries(dir) {
199
+ export async function collectAutoThemeEntries(dir) {
197
200
  return collectFlatEntries(dir, ".json");
198
201
  }
199
- export function resolveExtensionEntries(dir) {
202
+ export async function resolveExtensionEntries(dir) {
200
203
  const packageJsonPath = join(dir, "package.json");
201
- if (existsSync(packageJsonPath)) {
202
- const manifest = readPiManifestFile(packageJsonPath);
203
- if (manifest?.extensions?.length) {
204
- const entries = [];
205
- for (const extPath of manifest.extensions) {
206
- const resolvedExtPath = resolve(dir, extPath);
207
- if (existsSync(resolvedExtPath))
208
- entries.push(resolvedExtPath);
204
+ if (await exists(packageJsonPath)) {
205
+ try {
206
+ const pkg = JSON.parse(await readFile(packageJsonPath, "utf-8"));
207
+ const manifest = getManifestFromPackageJson(pkg);
208
+ if (manifest?.extensions?.length) {
209
+ const entries = [];
210
+ for (const extPath of manifest.extensions) {
211
+ const resolvedExtPath = resolve(dir, extPath);
212
+ if (await exists(resolvedExtPath))
213
+ entries.push(resolvedExtPath);
214
+ }
215
+ if (entries.length > 0)
216
+ return entries;
209
217
  }
210
- if (entries.length > 0)
211
- return entries;
212
218
  }
219
+ catch { }
213
220
  }
214
221
  const indexTs = join(dir, "index.ts");
215
222
  const indexJs = join(dir, "index.js");
216
- if (existsSync(indexTs))
223
+ if (await exists(indexTs))
217
224
  return [indexTs];
218
- if (existsSync(indexJs))
225
+ if (await exists(indexJs))
219
226
  return [indexJs];
220
227
  return null;
221
228
  }
222
- export function collectAutoExtensionEntries(dir) {
229
+ export async function collectAutoExtensionEntries(dir) {
223
230
  const entries = [];
224
- if (!existsSync(dir))
231
+ if (!(await exists(dir)))
225
232
  return entries;
226
- const rootEntries = resolveExtensionEntries(dir);
233
+ const rootEntries = await resolveExtensionEntries(dir);
227
234
  if (rootEntries)
228
235
  return rootEntries;
229
236
  const ig = ignore();
230
- addIgnoreRules(ig, dir, dir);
237
+ await addIgnoreRules(ig, dir, dir);
238
+ const startedAt = Date.now();
231
239
  try {
232
- const dirEntries = readdirSync(dir, { withFileTypes: true });
240
+ const dirEntries = await readdir(dir, { withFileTypes: true });
233
241
  for (const entry of dirEntries) {
242
+ await yieldToEventLoopIfSlow(startedAt, RESOURCE_DISCOVERY_YIELD_AFTER_MS);
234
243
  if (entry.name.startsWith(".") || entry.name === "node_modules")
235
244
  continue;
236
- const info = getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());
245
+ const info = await getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());
237
246
  if (!info)
238
247
  continue;
239
248
  const relPath = toPosixPath(relative(dir, info.fullPath));
240
249
  const ignorePath = info.isDir ? `${relPath}/` : relPath;
241
250
  if (ig.ignores(ignorePath))
242
251
  continue;
243
- if (info.isFile && (entry.name.endsWith(".ts") || entry.name.endsWith(".js"))) {
252
+ if (info.isFile && (entry.name.endsWith(".ts") || entry.name.endsWith(".js")))
244
253
  entries.push(info.fullPath);
245
- }
246
254
  else if (info.isDir) {
247
- const resolvedEntries = resolveExtensionEntries(info.fullPath);
255
+ const resolvedEntries = await resolveExtensionEntries(info.fullPath);
248
256
  if (resolvedEntries)
249
257
  entries.push(...resolvedEntries);
250
258
  }
@@ -253,13 +261,16 @@ export function collectAutoExtensionEntries(dir) {
253
261
  catch { }
254
262
  return entries;
255
263
  }
256
- export function collectResourceFiles(dir, resourceType) {
257
- if (resourceType === "skills") {
264
+ export async function collectResourceFiles(dir, resourceType) {
265
+ if (resourceType === "skills")
258
266
  return collectSkillEntries(dir, "pi");
259
- }
260
- if (resourceType === "extensions") {
267
+ if (resourceType === "extensions")
261
268
  return collectAutoExtensionEntries(dir);
262
- }
263
269
  return collectFiles(dir, FILE_PATTERNS[resourceType]);
264
270
  }
271
+ export function isPathUnder(target, root) {
272
+ const resolvedRoot = resolve(root);
273
+ const resolvedTarget = resolve(target);
274
+ return resolvedTarget === resolvedRoot || resolvedTarget.startsWith(resolvedRoot.endsWith(sep) ? resolvedRoot : `${resolvedRoot}${sep}`);
275
+ }
265
276
  //# sourceMappingURL=package-manager-resource-files.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"package-manager-resource-files.js","sourceRoot":"","sources":["../../src/core/package-manager-resource-files.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport ignore from \"ignore\";\nimport { readPiManifestFile } from \"./package-manager-manifest.ts\";\nimport { toPosixPath } from \"./package-manager-resource-patterns.ts\";\nimport { FILE_PATTERNS, type ResourceType } from \"./package-manager-types.ts\";\n\nconst IGNORE_FILE_NAMES = [\".gitignore\", \".ignore\", \".fdignore\"];\ntype IgnoreMatcher = ReturnType<typeof ignore>;\n\ntype DirEntryInfo = {\n\tfullPath: string;\n\tisDir: boolean;\n\tisFile: boolean;\n};\n\nfunction prefixIgnorePattern(line: string, prefix: string): string | null {\n\tconst trimmed = line.trim();\n\tif (!trimmed) return null;\n\tif (trimmed.startsWith(\"#\") && !trimmed.startsWith(\"\\\\#\")) return null;\n\n\tlet pattern = line;\n\tlet negated = false;\n\tif (pattern.startsWith(\"!\")) {\n\t\tnegated = true;\n\t\tpattern = pattern.slice(1);\n\t} else if (pattern.startsWith(\"\\\\!\")) {\n\t\tpattern = pattern.slice(1);\n\t}\n\tif (pattern.startsWith(\"/\")) {\n\t\tpattern = pattern.slice(1);\n\t}\n\n\tconst prefixed = prefix ? `${prefix}${pattern}` : pattern;\n\treturn negated ? `!${prefixed}` : prefixed;\n}\n\nfunction addIgnoreRules(ig: IgnoreMatcher, dir: string, rootDir: string): void {\n\tconst relativeDir = relative(rootDir, dir);\n\tconst prefix = relativeDir ? `${toPosixPath(relativeDir)}/` : \"\";\n\n\tfor (const filename of IGNORE_FILE_NAMES) {\n\t\tconst ignorePath = join(dir, filename);\n\t\tif (!existsSync(ignorePath)) continue;\n\t\ttry {\n\t\t\tconst content = readFileSync(ignorePath, \"utf-8\");\n\t\t\tconst patterns = content\n\t\t\t\t.split(/\\r?\\n/)\n\t\t\t\t.map((line) => prefixIgnorePattern(line, prefix))\n\t\t\t\t.filter((line): line is string => Boolean(line));\n\t\t\tif (patterns.length > 0) {\n\t\t\t\tig.add(patterns);\n\t\t\t}\n\t\t} catch {}\n\t}\n}\n\nfunction getEntryInfo(dir: string, name: string, isDirectory: boolean, isFileEntry: boolean, isSymlink: boolean): DirEntryInfo | null {\n\tconst fullPath = join(dir, name);\n\tlet isDir = isDirectory;\n\tlet isFile = isFileEntry;\n\tif (isSymlink) {\n\t\ttry {\n\t\t\tconst stats = statSync(fullPath);\n\t\t\tisDir = stats.isDirectory();\n\t\t\tisFile = stats.isFile();\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\treturn { fullPath, isDir, isFile };\n}\n\nexport function collectFiles(\n\tdir: string,\n\tfilePattern: RegExp,\n\tskipNodeModules = true,\n\tignoreMatcher?: IgnoreMatcher,\n\trootDir?: string,\n): string[] {\n\tconst files: string[] = [];\n\tif (!existsSync(dir)) return files;\n\n\tconst root = rootDir ?? dir;\n\tconst ig = ignoreMatcher ?? ignore();\n\taddIgnoreRules(ig, dir, root);\n\n\ttry {\n\t\tconst entries = readdirSync(dir, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\tif (entry.name.startsWith(\".\")) continue;\n\t\t\tif (skipNodeModules && entry.name === \"node_modules\") continue;\n\n\t\t\tconst info = getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());\n\t\t\tif (!info) continue;\n\n\t\t\tconst relPath = toPosixPath(relative(root, info.fullPath));\n\t\t\tconst ignorePath = info.isDir ? `${relPath}/` : relPath;\n\t\t\tif (ig.ignores(ignorePath)) continue;\n\n\t\t\tif (info.isDir) {\n\t\t\t\tfiles.push(...collectFiles(info.fullPath, filePattern, skipNodeModules, ig, root));\n\t\t\t} else if (info.isFile && filePattern.test(entry.name)) {\n\t\t\t\tfiles.push(info.fullPath);\n\t\t\t}\n\t\t}\n\t} catch {}\n\n\treturn files;\n}\n\ntype SkillDiscoveryMode = \"pi\" | \"agents\";\n\nfunction collectSkillEntries(\n\tdir: string,\n\tmode: SkillDiscoveryMode,\n\tignoreMatcher?: IgnoreMatcher,\n\trootDir?: string,\n): string[] {\n\tconst entries: string[] = [];\n\tif (!existsSync(dir)) return entries;\n\n\tconst root = rootDir ?? dir;\n\tconst ig = ignoreMatcher ?? ignore();\n\taddIgnoreRules(ig, dir, root);\n\n\ttry {\n\t\tconst dirEntries = readdirSync(dir, { withFileTypes: true });\n\t\tfor (const entry of dirEntries) {\n\t\t\tif (entry.name !== \"SKILL.md\") continue;\n\t\t\tconst info = getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());\n\t\t\tif (!info) continue;\n\t\t\tconst relPath = toPosixPath(relative(root, info.fullPath));\n\t\t\tif (info.isFile && !ig.ignores(relPath)) {\n\t\t\t\tentries.push(info.fullPath);\n\t\t\t\treturn entries;\n\t\t\t}\n\t\t}\n\n\t\tfor (const entry of dirEntries) {\n\t\t\tif (entry.name.startsWith(\".\")) continue;\n\t\t\tif (entry.name === \"node_modules\") continue;\n\t\t\tconst info = getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());\n\t\t\tif (!info) continue;\n\n\t\t\tconst relPath = toPosixPath(relative(root, info.fullPath));\n\t\t\tif (mode === \"pi\" && dir === root && info.isFile && entry.name.endsWith(\".md\") && !ig.ignores(relPath)) {\n\t\t\t\tentries.push(info.fullPath);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!info.isDir || ig.ignores(`${relPath}/`)) continue;\n\t\t\tentries.push(...collectSkillEntries(info.fullPath, mode, ig, root));\n\t\t}\n\t} catch {}\n\n\treturn entries;\n}\n\nexport function collectAutoSkillEntries(dir: string, mode: SkillDiscoveryMode): string[] {\n\treturn collectSkillEntries(dir, mode);\n}\n\nfunction findGitRepoRoot(startDir: string): string | null {\n\tlet dir = resolve(startDir);\n\twhile (true) {\n\t\tif (existsSync(join(dir, \".git\"))) return dir;\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return null;\n\t\tdir = parent;\n\t}\n}\n\nexport function collectAncestorAgentsSkillDirs(startDir: string): string[] {\n\tconst skillDirs: string[] = [];\n\tconst resolvedStartDir = resolve(startDir);\n\tconst gitRepoRoot = findGitRepoRoot(resolvedStartDir);\n\n\tlet dir = resolvedStartDir;\n\twhile (true) {\n\t\tskillDirs.push(join(dir, \".agents\", \"skills\"));\n\t\tif (gitRepoRoot && dir === gitRepoRoot) break;\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) break;\n\t\tdir = parent;\n\t}\n\treturn skillDirs;\n}\n\nfunction collectFlatEntries(dir: string, extension: string): string[] {\n\tconst entries: string[] = [];\n\tif (!existsSync(dir)) return entries;\n\n\tconst ig = ignore();\n\taddIgnoreRules(ig, dir, dir);\n\ttry {\n\t\tconst dirEntries = readdirSync(dir, { withFileTypes: true });\n\t\tfor (const entry of dirEntries) {\n\t\t\tif (entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue;\n\t\t\tconst info = getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());\n\t\t\tif (!info) continue;\n\t\t\tconst relPath = toPosixPath(relative(dir, info.fullPath));\n\t\t\tif (ig.ignores(relPath)) continue;\n\t\t\tif (info.isFile && entry.name.endsWith(extension)) entries.push(info.fullPath);\n\t\t}\n\t} catch {}\n\treturn entries;\n}\n\nexport function collectAutoPromptEntries(dir: string): string[] {\n\treturn collectFlatEntries(dir, \".md\");\n}\n\nexport function collectAutoThemeEntries(dir: string): string[] {\n\treturn collectFlatEntries(dir, \".json\");\n}\n\nexport function resolveExtensionEntries(dir: string): string[] | null {\n\tconst packageJsonPath = join(dir, \"package.json\");\n\tif (existsSync(packageJsonPath)) {\n\t\tconst manifest = readPiManifestFile(packageJsonPath);\n\t\tif (manifest?.extensions?.length) {\n\t\t\tconst entries: string[] = [];\n\t\t\tfor (const extPath of manifest.extensions) {\n\t\t\t\tconst resolvedExtPath = resolve(dir, extPath);\n\t\t\t\tif (existsSync(resolvedExtPath)) entries.push(resolvedExtPath);\n\t\t\t}\n\t\t\tif (entries.length > 0) return entries;\n\t\t}\n\t}\n\n\tconst indexTs = join(dir, \"index.ts\");\n\tconst indexJs = join(dir, \"index.js\");\n\tif (existsSync(indexTs)) return [indexTs];\n\tif (existsSync(indexJs)) return [indexJs];\n\treturn null;\n}\n\nexport function collectAutoExtensionEntries(dir: string): string[] {\n\tconst entries: string[] = [];\n\tif (!existsSync(dir)) return entries;\n\n\tconst rootEntries = resolveExtensionEntries(dir);\n\tif (rootEntries) return rootEntries;\n\n\tconst ig = ignore();\n\taddIgnoreRules(ig, dir, dir);\n\ttry {\n\t\tconst dirEntries = readdirSync(dir, { withFileTypes: true });\n\t\tfor (const entry of dirEntries) {\n\t\t\tif (entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue;\n\t\t\tconst info = getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());\n\t\t\tif (!info) continue;\n\n\t\t\tconst relPath = toPosixPath(relative(dir, info.fullPath));\n\t\t\tconst ignorePath = info.isDir ? `${relPath}/` : relPath;\n\t\t\tif (ig.ignores(ignorePath)) continue;\n\n\t\t\tif (info.isFile && (entry.name.endsWith(\".ts\") || entry.name.endsWith(\".js\"))) {\n\t\t\t\tentries.push(info.fullPath);\n\t\t\t} else if (info.isDir) {\n\t\t\t\tconst resolvedEntries = resolveExtensionEntries(info.fullPath);\n\t\t\t\tif (resolvedEntries) entries.push(...resolvedEntries);\n\t\t\t}\n\t\t}\n\t} catch {}\n\treturn entries;\n}\n\nexport function collectResourceFiles(dir: string, resourceType: ResourceType): string[] {\n\tif (resourceType === \"skills\") {\n\t\treturn collectSkillEntries(dir, \"pi\");\n\t}\n\tif (resourceType === \"extensions\") {\n\t\treturn collectAutoExtensionEntries(dir);\n\t}\n\treturn collectFiles(dir, FILE_PATTERNS[resourceType]);\n}\n"]}
1
+ {"version":3,"file":"package-manager-resource-files.js","sourceRoot":"","sources":["../../src/core/package-manager-resource-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAqB,MAAM,4BAA4B,CAAC;AAE9E,MAAM,iBAAiB,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AACjE,MAAM,iCAAiC,GAAG,CAAC,CAAC;AAU5C,KAAK,UAAU,MAAM,CAAC,IAAY;IACjC,IAAI,CAAC;QAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;AACjE,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY,EAAE,MAAc;IACxD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACrF,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAAC,OAAO,GAAG,IAAI,CAAC;QAAC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC;SACvE,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/D,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IAC1D,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,EAAiB,EAAE,GAAW,EAAE,OAAe;IAC5E,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,KAAK,MAAM,QAAQ,IAAI,iBAAiB,EAAE,CAAC;QAC1C,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;YAC7D,MAAM,QAAQ,GAAG,OAAO;iBACtB,KAAK,CAAC,OAAO,CAAC;iBACd,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;iBAChD,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YAClD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;gBAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACX,CAAC;AACF,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,IAAY,EAAE,WAAoB,EAAE,WAAoB,EAAE,SAAkB;IACpH,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACjC,IAAI,KAAK,GAAG,WAAW,CAAC;IACxB,IAAI,MAAM,GAAG,WAAW,CAAC;IACzB,IAAI,SAAS,EAAE,CAAC;QACf,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;YACnC,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;YAC5B,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;IACzB,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,WAAmB,EAAE,eAAe,GAAG,IAAI,EAAE,aAA6B,EAAE,OAAgB;IAC3I,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,IAAI,GAAG,OAAO,IAAI,GAAG,CAAC;IAC5B,MAAM,EAAE,GAAG,aAAa,IAAI,MAAM,EAAE,CAAC;IACrC,MAAM,cAAc,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,sBAAsB,CAAC,SAAS,EAAE,iCAAiC,CAAC,CAAC;YAC3E,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC;gBAAE,SAAS;YAC/F,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;YAC9G,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC3D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;YACxD,IAAI,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC;gBAAE,SAAS;YACrC,IAAI,IAAI,CAAC,KAAK;gBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;iBACpG,IAAI,IAAI,CAAC,MAAM,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjF,CAAC;IACF,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,KAAK,CAAC;AACd,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,GAAW,EAAE,IAAwB,EAAE,aAA6B,EAAE,OAAgB;IACxH,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC;IACzC,MAAM,IAAI,GAAG,OAAO,IAAI,GAAG,CAAC;IAC5B,MAAM,EAAE,GAAG,aAAa,IAAI,MAAM,EAAE,CAAC;IACrC,MAAM,cAAc,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,CAAC;QACJ,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YAChC,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;gBAAE,SAAS;YACxC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;YAC9G,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC3D,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAAC,OAAO,OAAO,CAAC;YAAC,CAAC;QAC1F,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YAChC,MAAM,sBAAsB,CAAC,SAAS,EAAE,iCAAiC,CAAC,CAAC;YAC3E,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;gBAAE,SAAS;YAC1E,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;YAC9G,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC3D,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBACxG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC5B,SAAS;YACV,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,CAAC;gBAAE,SAAS;YACvD,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;QAC3E,CAAC;IACF,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,GAAW,EAAE,IAAwB;IAClF,OAAO,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,QAAgB;IAC9C,IAAI,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5B,OAAO,IAAI,EAAE,CAAC;QACb,IAAI,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QAChD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAChC,GAAG,GAAG,MAAM,CAAC;IACd,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,QAAgB;IACpE,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,gBAAgB,CAAC,CAAC;IAC5D,IAAI,GAAG,GAAG,gBAAgB,CAAC;IAC3B,OAAO,IAAI,EAAE,CAAC;QACb,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC/C,IAAI,WAAW,IAAI,GAAG,KAAK,WAAW;YAAE,MAAM;QAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACd,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,GAAW,EAAE,SAAiB;IAC/D,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC;IACzC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IACpB,MAAM,cAAc,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,CAAC;QACJ,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YAChC,MAAM,sBAAsB,CAAC,SAAS,EAAE,iCAAiC,CAAC,CAAC;YAC3E,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;gBAAE,SAAS;YAC1E,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;YAC9G,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC1D,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;gBAAE,SAAS;YAClC,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChF,CAAC;IACF,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,GAAW;IACzD,OAAO,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,GAAW;IACxD,OAAO,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,GAAW;IACxD,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAClD,IAAI,MAAM,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAA4B,CAAC;YAC5F,MAAM,QAAQ,GAAG,0BAA0B,CAAC,GAAG,CAAC,CAAC;YACjD,IAAI,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;gBAClC,MAAM,OAAO,GAAa,EAAE,CAAC;gBAC7B,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;oBAC3C,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;oBAC9C,IAAI,MAAM,MAAM,CAAC,eAAe,CAAC;wBAAE,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;gBAClE,CAAC;gBACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;oBAAE,OAAO,OAAO,CAAC;YACxC,CAAC;QACF,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACX,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACtC,IAAI,MAAM,MAAM,CAAC,OAAO,CAAC;QAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,MAAM,MAAM,CAAC,OAAO,CAAC;QAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,GAAW;IAC5D,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC;IACzC,MAAM,WAAW,GAAG,MAAM,uBAAuB,CAAC,GAAG,CAAC,CAAC;IACvD,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IACpC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IACpB,MAAM,cAAc,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,CAAC;QACJ,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YAChC,MAAM,sBAAsB,CAAC,SAAS,EAAE,iCAAiC,CAAC,CAAC;YAC3E,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;gBAAE,SAAS;YAC1E,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;YAC9G,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;YACxD,IAAI,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC;gBAAE,SAAS;YACrC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;iBACtG,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACrB,MAAM,eAAe,GAAG,MAAM,uBAAuB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACrE,IAAI,eAAe;oBAAE,OAAO,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,CAAC;YACvD,CAAC;QACF,CAAC;IACF,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,GAAW,EAAE,YAA0B;IACjF,IAAI,YAAY,KAAK,QAAQ;QAAE,OAAO,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACrE,IAAI,YAAY,KAAK,YAAY;QAAE,OAAO,2BAA2B,CAAC,GAAG,CAAC,CAAC;IAC3E,OAAO,YAAY,CAAC,GAAG,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,IAAY;IACvD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,OAAO,cAAc,KAAK,YAAY,IAAI,cAAc,CAAC,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,GAAG,GAAG,EAAE,CAAC,CAAC;AAC1I,CAAC","sourcesContent":["import { access, readdir, readFile, stat } from \"node:fs/promises\";\nimport { dirname, join, relative, resolve, sep } from \"node:path\";\nimport ignore from \"ignore\";\nimport { yieldToEventLoopIfSlow } from \"../utils/event-loop.ts\";\nimport { getManifestFromPackageJson } from \"./package-manager-manifest.ts\";\nimport { toPosixPath } from \"./package-manager-resource-patterns.ts\";\nimport { FILE_PATTERNS, type ResourceType } from \"./package-manager-types.ts\";\n\nconst IGNORE_FILE_NAMES = [\".gitignore\", \".ignore\", \".fdignore\"];\nconst RESOURCE_DISCOVERY_YIELD_AFTER_MS = 8;\ntype IgnoreMatcher = ReturnType<typeof ignore>;\ntype SkillDiscoveryMode = \"pi\" | \"agents\";\n\ntype DirEntryInfo = {\n\tfullPath: string;\n\tisDir: boolean;\n\tisFile: boolean;\n};\n\nasync function exists(path: string): Promise<boolean> {\n\ttry { await access(path); return true; } catch { return false; }\n}\n\nfunction prefixIgnorePattern(line: string, prefix: string): string | null {\n\tconst trimmed = line.trim();\n\tif (!trimmed || (trimmed.startsWith(\"#\") && !trimmed.startsWith(\"\\\\#\"))) return null;\n\tlet pattern = line;\n\tlet negated = false;\n\tif (pattern.startsWith(\"!\")) { negated = true; pattern = pattern.slice(1); }\n\telse if (pattern.startsWith(\"\\\\!\")) pattern = pattern.slice(1);\n\tif (pattern.startsWith(\"/\")) pattern = pattern.slice(1);\n\tconst prefixed = prefix ? `${prefix}${pattern}` : pattern;\n\treturn negated ? `!${prefixed}` : prefixed;\n}\n\nasync function addIgnoreRules(ig: IgnoreMatcher, dir: string, rootDir: string): Promise<void> {\n\tconst relativeDir = relative(rootDir, dir);\n\tconst prefix = relativeDir ? `${toPosixPath(relativeDir)}/` : \"\";\n\tfor (const filename of IGNORE_FILE_NAMES) {\n\t\ttry {\n\t\t\tconst content = await readFile(join(dir, filename), \"utf-8\");\n\t\t\tconst patterns = content\n\t\t\t\t.split(/\\r?\\n/)\n\t\t\t\t.map((line) => prefixIgnorePattern(line, prefix))\n\t\t\t\t.filter((line): line is string => Boolean(line));\n\t\t\tif (patterns.length > 0) ig.add(patterns);\n\t\t} catch {}\n\t}\n}\n\nasync function getEntryInfo(dir: string, name: string, isDirectory: boolean, isFileEntry: boolean, isSymlink: boolean): Promise<DirEntryInfo | null> {\n\tconst fullPath = join(dir, name);\n\tlet isDir = isDirectory;\n\tlet isFile = isFileEntry;\n\tif (isSymlink) {\n\t\ttry {\n\t\t\tconst stats = await stat(fullPath);\n\t\t\tisDir = stats.isDirectory();\n\t\t\tisFile = stats.isFile();\n\t\t} catch { return null; }\n\t}\n\treturn { fullPath, isDir, isFile };\n}\n\nexport async function collectFiles(dir: string, filePattern: RegExp, skipNodeModules = true, ignoreMatcher?: IgnoreMatcher, rootDir?: string): Promise<string[]> {\n\tconst files: string[] = [];\n\tif (!(await exists(dir))) return files;\n\tconst root = rootDir ?? dir;\n\tconst ig = ignoreMatcher ?? ignore();\n\tawait addIgnoreRules(ig, dir, root);\n\tconst startedAt = Date.now();\n\ttry {\n\t\tconst entries = await readdir(dir, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\tawait yieldToEventLoopIfSlow(startedAt, RESOURCE_DISCOVERY_YIELD_AFTER_MS);\n\t\t\tif (entry.name.startsWith(\".\") || (skipNodeModules && entry.name === \"node_modules\")) continue;\n\t\t\tconst info = await getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());\n\t\t\tif (!info) continue;\n\t\t\tconst relPath = toPosixPath(relative(root, info.fullPath));\n\t\t\tconst ignorePath = info.isDir ? `${relPath}/` : relPath;\n\t\t\tif (ig.ignores(ignorePath)) continue;\n\t\t\tif (info.isDir) files.push(...await collectFiles(info.fullPath, filePattern, skipNodeModules, ig, root));\n\t\t\telse if (info.isFile && filePattern.test(entry.name)) files.push(info.fullPath);\n\t\t}\n\t} catch {}\n\treturn files;\n}\n\nasync function collectSkillEntries(dir: string, mode: SkillDiscoveryMode, ignoreMatcher?: IgnoreMatcher, rootDir?: string): Promise<string[]> {\n\tconst entries: string[] = [];\n\tif (!(await exists(dir))) return entries;\n\tconst root = rootDir ?? dir;\n\tconst ig = ignoreMatcher ?? ignore();\n\tawait addIgnoreRules(ig, dir, root);\n\tconst startedAt = Date.now();\n\ttry {\n\t\tconst dirEntries = await readdir(dir, { withFileTypes: true });\n\t\tfor (const entry of dirEntries) {\n\t\t\tif (entry.name !== \"SKILL.md\") continue;\n\t\t\tconst info = await getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());\n\t\t\tif (!info) continue;\n\t\t\tconst relPath = toPosixPath(relative(root, info.fullPath));\n\t\t\tif (info.isFile && !ig.ignores(relPath)) { entries.push(info.fullPath); return entries; }\n\t\t}\n\t\tfor (const entry of dirEntries) {\n\t\t\tawait yieldToEventLoopIfSlow(startedAt, RESOURCE_DISCOVERY_YIELD_AFTER_MS);\n\t\t\tif (entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue;\n\t\t\tconst info = await getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());\n\t\t\tif (!info) continue;\n\t\t\tconst relPath = toPosixPath(relative(root, info.fullPath));\n\t\t\tif (mode === \"pi\" && dir === root && info.isFile && entry.name.endsWith(\".md\") && !ig.ignores(relPath)) {\n\t\t\t\tentries.push(info.fullPath);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!info.isDir || ig.ignores(`${relPath}/`)) continue;\n\t\t\tentries.push(...await collectSkillEntries(info.fullPath, mode, ig, root));\n\t\t}\n\t} catch {}\n\treturn entries;\n}\n\nexport async function collectAutoSkillEntries(dir: string, mode: SkillDiscoveryMode): Promise<string[]> {\n\treturn collectSkillEntries(dir, mode);\n}\n\nasync function findGitRepoRoot(startDir: string): Promise<string | null> {\n\tlet dir = resolve(startDir);\n\twhile (true) {\n\t\tif (await exists(join(dir, \".git\"))) return dir;\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return null;\n\t\tdir = parent;\n\t}\n}\n\nexport async function collectAncestorAgentsSkillDirs(startDir: string): Promise<string[]> {\n\tconst skillDirs: string[] = [];\n\tconst resolvedStartDir = resolve(startDir);\n\tconst gitRepoRoot = await findGitRepoRoot(resolvedStartDir);\n\tlet dir = resolvedStartDir;\n\twhile (true) {\n\t\tskillDirs.push(join(dir, \".agents\", \"skills\"));\n\t\tif (gitRepoRoot && dir === gitRepoRoot) break;\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) break;\n\t\tdir = parent;\n\t}\n\treturn skillDirs;\n}\n\nasync function collectFlatEntries(dir: string, extension: string): Promise<string[]> {\n\tconst entries: string[] = [];\n\tif (!(await exists(dir))) return entries;\n\tconst ig = ignore();\n\tawait addIgnoreRules(ig, dir, dir);\n\tconst startedAt = Date.now();\n\ttry {\n\t\tconst dirEntries = await readdir(dir, { withFileTypes: true });\n\t\tfor (const entry of dirEntries) {\n\t\t\tawait yieldToEventLoopIfSlow(startedAt, RESOURCE_DISCOVERY_YIELD_AFTER_MS);\n\t\t\tif (entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue;\n\t\t\tconst info = await getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());\n\t\t\tif (!info) continue;\n\t\t\tconst relPath = toPosixPath(relative(dir, info.fullPath));\n\t\t\tif (ig.ignores(relPath)) continue;\n\t\t\tif (info.isFile && entry.name.endsWith(extension)) entries.push(info.fullPath);\n\t\t}\n\t} catch {}\n\treturn entries;\n}\n\nexport async function collectAutoPromptEntries(dir: string): Promise<string[]> {\n\treturn collectFlatEntries(dir, \".md\");\n}\n\nexport async function collectAutoThemeEntries(dir: string): Promise<string[]> {\n\treturn collectFlatEntries(dir, \".json\");\n}\n\nexport async function resolveExtensionEntries(dir: string): Promise<string[] | null> {\n\tconst packageJsonPath = join(dir, \"package.json\");\n\tif (await exists(packageJsonPath)) {\n\t\ttry {\n\t\t\tconst pkg = JSON.parse(await readFile(packageJsonPath, \"utf-8\")) as Record<string, unknown>;\n\t\t\tconst manifest = getManifestFromPackageJson(pkg);\n\t\t\tif (manifest?.extensions?.length) {\n\t\t\t\tconst entries: string[] = [];\n\t\t\t\tfor (const extPath of manifest.extensions) {\n\t\t\t\t\tconst resolvedExtPath = resolve(dir, extPath);\n\t\t\t\t\tif (await exists(resolvedExtPath)) entries.push(resolvedExtPath);\n\t\t\t\t}\n\t\t\t\tif (entries.length > 0) return entries;\n\t\t\t}\n\t\t} catch {}\n\t}\n\tconst indexTs = join(dir, \"index.ts\");\n\tconst indexJs = join(dir, \"index.js\");\n\tif (await exists(indexTs)) return [indexTs];\n\tif (await exists(indexJs)) return [indexJs];\n\treturn null;\n}\n\nexport async function collectAutoExtensionEntries(dir: string): Promise<string[]> {\n\tconst entries: string[] = [];\n\tif (!(await exists(dir))) return entries;\n\tconst rootEntries = await resolveExtensionEntries(dir);\n\tif (rootEntries) return rootEntries;\n\tconst ig = ignore();\n\tawait addIgnoreRules(ig, dir, dir);\n\tconst startedAt = Date.now();\n\ttry {\n\t\tconst dirEntries = await readdir(dir, { withFileTypes: true });\n\t\tfor (const entry of dirEntries) {\n\t\t\tawait yieldToEventLoopIfSlow(startedAt, RESOURCE_DISCOVERY_YIELD_AFTER_MS);\n\t\t\tif (entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue;\n\t\t\tconst info = await getEntryInfo(dir, entry.name, entry.isDirectory(), entry.isFile(), entry.isSymbolicLink());\n\t\t\tif (!info) continue;\n\t\t\tconst relPath = toPosixPath(relative(dir, info.fullPath));\n\t\t\tconst ignorePath = info.isDir ? `${relPath}/` : relPath;\n\t\t\tif (ig.ignores(ignorePath)) continue;\n\t\t\tif (info.isFile && (entry.name.endsWith(\".ts\") || entry.name.endsWith(\".js\"))) entries.push(info.fullPath);\n\t\t\telse if (info.isDir) {\n\t\t\t\tconst resolvedEntries = await resolveExtensionEntries(info.fullPath);\n\t\t\t\tif (resolvedEntries) entries.push(...resolvedEntries);\n\t\t\t}\n\t\t}\n\t} catch {}\n\treturn entries;\n}\n\nexport async function collectResourceFiles(dir: string, resourceType: ResourceType): Promise<string[]> {\n\tif (resourceType === \"skills\") return collectSkillEntries(dir, \"pi\");\n\tif (resourceType === \"extensions\") return collectAutoExtensionEntries(dir);\n\treturn collectFiles(dir, FILE_PATTERNS[resourceType]);\n}\n\nexport function isPathUnder(target: string, root: string): boolean {\n\tconst resolvedRoot = resolve(root);\n\tconst resolvedTarget = resolve(target);\n\treturn resolvedTarget === resolvedRoot || resolvedTarget.startsWith(resolvedRoot.endsWith(sep) ? resolvedRoot : `${resolvedRoot}${sep}`);\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { LoadPromptTemplatesOptions, PromptTemplate } from "./prompt-templates.ts";
2
+ export declare function loadPromptTemplatesAsync(options: LoadPromptTemplatesOptions): Promise<PromptTemplate[]>;
3
+ //# sourceMappingURL=prompt-templates-async.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-templates-async.d.ts","sourceRoot":"","sources":["../../src/core/prompt-templates-async.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,0BAA0B,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAuDxF,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CA0C7G","sourcesContent":["import { access, readdir, readFile, stat } from \"node:fs/promises\";\nimport { basename, dirname, join, resolve, sep } from \"node:path\";\nimport { CONFIG_DIR_NAME } from \"../config.ts\";\nimport { parseFrontmatter } from \"../utils/frontmatter.ts\";\nimport { yieldToEventLoopIfSlow } from \"../utils/event-loop.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { createSyntheticSourceInfo, type SourceInfo } from \"./source-info.ts\";\nimport type { LoadPromptTemplatesOptions, PromptTemplate } from \"./prompt-templates.ts\";\n\nconst YIELD_AFTER_MS = 8;\n\nasync function exists(path: string): Promise<boolean> {\n\ttry { await access(path); return true; } catch { return false; }\n}\n\nasync function loadTemplateFromFile(filePath: string, sourceInfo: SourceInfo): Promise<PromptTemplate | null> {\n\ttry {\n\t\tconst rawContent = await readFile(filePath, \"utf-8\");\n\t\tconst { frontmatter, body } = parseFrontmatter<Record<string, string>>(rawContent);\n\t\tconst name = basename(filePath).replace(/\\.md$/, \"\");\n\t\tlet description = frontmatter.description || \"\";\n\t\tif (!description) {\n\t\t\tconst firstLine = body.split(\"\\n\").find((line) => line.trim());\n\t\t\tif (firstLine) description = firstLine.length > 60 ? `${firstLine.slice(0, 60)}...` : firstLine;\n\t\t}\n\t\treturn {\n\t\t\tname,\n\t\t\tdescription,\n\t\t\t...(frontmatter[\"argument-hint\"] && { argumentHint: frontmatter[\"argument-hint\"] }),\n\t\t\tcontent: body,\n\t\t\tsourceInfo,\n\t\t\tfilePath,\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function loadTemplatesFromDir(\n\tdir: string,\n\tgetSourceInfo: (filePath: string) => Promise<SourceInfo>,\n): Promise<PromptTemplate[]> {\n\tconst templates: PromptTemplate[] = [];\n\tif (!(await exists(dir))) return templates;\n\tconst startedAt = Date.now();\n\ttry {\n\t\tconst entries = await readdir(dir, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\tawait yieldToEventLoopIfSlow(startedAt, YIELD_AFTER_MS);\n\t\t\tconst fullPath = join(dir, entry.name);\n\t\t\tlet isFile = entry.isFile();\n\t\t\tif (entry.isSymbolicLink()) {\n\t\t\t\ttry { isFile = (await stat(fullPath)).isFile(); } catch { continue; }\n\t\t\t}\n\t\t\tif (!isFile || !entry.name.endsWith(\".md\")) continue;\n\t\t\tconst template = await loadTemplateFromFile(fullPath, await getSourceInfo(fullPath));\n\t\t\tif (template) templates.push(template);\n\t\t}\n\t} catch {}\n\treturn templates;\n}\n\nexport async function loadPromptTemplatesAsync(options: LoadPromptTemplatesOptions): Promise<PromptTemplate[]> {\n\tconst resolvedCwd = resolvePath(options.cwd);\n\tconst resolvedAgentDir = resolvePath(options.agentDir);\n\tconst promptPaths = options.promptPaths ?? [];\n\tconst includeDefaults = options.includeDefaults ?? true;\n\tconst templates: PromptTemplate[] = [];\n\tconst globalPromptsDir = join(resolvedAgentDir, \"prompts\");\n\tconst projectPromptsDir = resolve(resolvedCwd, CONFIG_DIR_NAME, \"prompts\");\n\tconst isUnderPath = (target: string, root: string): boolean => {\n\t\tconst normalizedRoot = resolve(root);\n\t\treturn target === normalizedRoot || target.startsWith(normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`);\n\t};\n\tconst getSourceInfo = async (resolvedPath: string): Promise<SourceInfo> => {\n\t\tif (isUnderPath(resolvedPath, globalPromptsDir)) {\n\t\t\treturn createSyntheticSourceInfo(resolvedPath, { source: \"local\", scope: \"user\", baseDir: globalPromptsDir });\n\t\t}\n\t\tif (isUnderPath(resolvedPath, projectPromptsDir)) {\n\t\t\treturn createSyntheticSourceInfo(resolvedPath, { source: \"local\", scope: \"project\", baseDir: projectPromptsDir });\n\t\t}\n\t\tconst stats = await stat(resolvedPath);\n\t\treturn createSyntheticSourceInfo(resolvedPath, { source: \"local\", baseDir: stats.isDirectory() ? resolvedPath : dirname(resolvedPath) });\n\t};\n\tif (includeDefaults) {\n\t\ttemplates.push(...await loadTemplatesFromDir(globalPromptsDir, getSourceInfo));\n\t\ttemplates.push(...await loadTemplatesFromDir(projectPromptsDir, getSourceInfo));\n\t}\n\tconst startedAt = Date.now();\n\tfor (const rawPath of promptPaths) {\n\t\tawait yieldToEventLoopIfSlow(startedAt, YIELD_AFTER_MS);\n\t\tconst resolvedPath = resolvePath(rawPath, resolvedCwd, { trim: true });\n\t\tif (!(await exists(resolvedPath))) continue;\n\t\ttry {\n\t\t\tconst stats = await stat(resolvedPath);\n\t\t\tif (stats.isDirectory()) {\n\t\t\t\ttemplates.push(...await loadTemplatesFromDir(resolvedPath, getSourceInfo));\n\t\t\t} else if (stats.isFile() && resolvedPath.endsWith(\".md\")) {\n\t\t\t\tconst template = await loadTemplateFromFile(resolvedPath, await getSourceInfo(resolvedPath));\n\t\t\t\tif (template) templates.push(template);\n\t\t\t}\n\t\t} catch {}\n\t}\n\treturn templates;\n}\n"]}
@@ -0,0 +1,118 @@
1
+ import { access, readdir, readFile, stat } from "node:fs/promises";
2
+ import { basename, dirname, join, resolve, sep } from "node:path";
3
+ import { CONFIG_DIR_NAME } from "../config.js";
4
+ import { parseFrontmatter } from "../utils/frontmatter.js";
5
+ import { yieldToEventLoopIfSlow } from "../utils/event-loop.js";
6
+ import { resolvePath } from "../utils/paths.js";
7
+ import { createSyntheticSourceInfo } from "./source-info.js";
8
+ const YIELD_AFTER_MS = 8;
9
+ async function exists(path) {
10
+ try {
11
+ await access(path);
12
+ return true;
13
+ }
14
+ catch {
15
+ return false;
16
+ }
17
+ }
18
+ async function loadTemplateFromFile(filePath, sourceInfo) {
19
+ try {
20
+ const rawContent = await readFile(filePath, "utf-8");
21
+ const { frontmatter, body } = parseFrontmatter(rawContent);
22
+ const name = basename(filePath).replace(/\.md$/, "");
23
+ let description = frontmatter.description || "";
24
+ if (!description) {
25
+ const firstLine = body.split("\n").find((line) => line.trim());
26
+ if (firstLine)
27
+ description = firstLine.length > 60 ? `${firstLine.slice(0, 60)}...` : firstLine;
28
+ }
29
+ return {
30
+ name,
31
+ description,
32
+ ...(frontmatter["argument-hint"] && { argumentHint: frontmatter["argument-hint"] }),
33
+ content: body,
34
+ sourceInfo,
35
+ filePath,
36
+ };
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ }
42
+ async function loadTemplatesFromDir(dir, getSourceInfo) {
43
+ const templates = [];
44
+ if (!(await exists(dir)))
45
+ return templates;
46
+ const startedAt = Date.now();
47
+ try {
48
+ const entries = await readdir(dir, { withFileTypes: true });
49
+ for (const entry of entries) {
50
+ await yieldToEventLoopIfSlow(startedAt, YIELD_AFTER_MS);
51
+ const fullPath = join(dir, entry.name);
52
+ let isFile = entry.isFile();
53
+ if (entry.isSymbolicLink()) {
54
+ try {
55
+ isFile = (await stat(fullPath)).isFile();
56
+ }
57
+ catch {
58
+ continue;
59
+ }
60
+ }
61
+ if (!isFile || !entry.name.endsWith(".md"))
62
+ continue;
63
+ const template = await loadTemplateFromFile(fullPath, await getSourceInfo(fullPath));
64
+ if (template)
65
+ templates.push(template);
66
+ }
67
+ }
68
+ catch { }
69
+ return templates;
70
+ }
71
+ export async function loadPromptTemplatesAsync(options) {
72
+ const resolvedCwd = resolvePath(options.cwd);
73
+ const resolvedAgentDir = resolvePath(options.agentDir);
74
+ const promptPaths = options.promptPaths ?? [];
75
+ const includeDefaults = options.includeDefaults ?? true;
76
+ const templates = [];
77
+ const globalPromptsDir = join(resolvedAgentDir, "prompts");
78
+ const projectPromptsDir = resolve(resolvedCwd, CONFIG_DIR_NAME, "prompts");
79
+ const isUnderPath = (target, root) => {
80
+ const normalizedRoot = resolve(root);
81
+ return target === normalizedRoot || target.startsWith(normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`);
82
+ };
83
+ const getSourceInfo = async (resolvedPath) => {
84
+ if (isUnderPath(resolvedPath, globalPromptsDir)) {
85
+ return createSyntheticSourceInfo(resolvedPath, { source: "local", scope: "user", baseDir: globalPromptsDir });
86
+ }
87
+ if (isUnderPath(resolvedPath, projectPromptsDir)) {
88
+ return createSyntheticSourceInfo(resolvedPath, { source: "local", scope: "project", baseDir: projectPromptsDir });
89
+ }
90
+ const stats = await stat(resolvedPath);
91
+ return createSyntheticSourceInfo(resolvedPath, { source: "local", baseDir: stats.isDirectory() ? resolvedPath : dirname(resolvedPath) });
92
+ };
93
+ if (includeDefaults) {
94
+ templates.push(...await loadTemplatesFromDir(globalPromptsDir, getSourceInfo));
95
+ templates.push(...await loadTemplatesFromDir(projectPromptsDir, getSourceInfo));
96
+ }
97
+ const startedAt = Date.now();
98
+ for (const rawPath of promptPaths) {
99
+ await yieldToEventLoopIfSlow(startedAt, YIELD_AFTER_MS);
100
+ const resolvedPath = resolvePath(rawPath, resolvedCwd, { trim: true });
101
+ if (!(await exists(resolvedPath)))
102
+ continue;
103
+ try {
104
+ const stats = await stat(resolvedPath);
105
+ if (stats.isDirectory()) {
106
+ templates.push(...await loadTemplatesFromDir(resolvedPath, getSourceInfo));
107
+ }
108
+ else if (stats.isFile() && resolvedPath.endsWith(".md")) {
109
+ const template = await loadTemplateFromFile(resolvedPath, await getSourceInfo(resolvedPath));
110
+ if (template)
111
+ templates.push(template);
112
+ }
113
+ }
114
+ catch { }
115
+ }
116
+ return templates;
117
+ }
118
+ //# sourceMappingURL=prompt-templates-async.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-templates-async.js","sourceRoot":"","sources":["../../src/core/prompt-templates-async.ts"],"names":[],"mappings":"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","sourcesContent":["import { access, readdir, readFile, stat } from \"node:fs/promises\";\nimport { basename, dirname, join, resolve, sep } from \"node:path\";\nimport { CONFIG_DIR_NAME } from \"../config.ts\";\nimport { parseFrontmatter } from \"../utils/frontmatter.ts\";\nimport { yieldToEventLoopIfSlow } from \"../utils/event-loop.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { createSyntheticSourceInfo, type SourceInfo } from \"./source-info.ts\";\nimport type { LoadPromptTemplatesOptions, PromptTemplate } from \"./prompt-templates.ts\";\n\nconst YIELD_AFTER_MS = 8;\n\nasync function exists(path: string): Promise<boolean> {\n\ttry { await access(path); return true; } catch { return false; }\n}\n\nasync function loadTemplateFromFile(filePath: string, sourceInfo: SourceInfo): Promise<PromptTemplate | null> {\n\ttry {\n\t\tconst rawContent = await readFile(filePath, \"utf-8\");\n\t\tconst { frontmatter, body } = parseFrontmatter<Record<string, string>>(rawContent);\n\t\tconst name = basename(filePath).replace(/\\.md$/, \"\");\n\t\tlet description = frontmatter.description || \"\";\n\t\tif (!description) {\n\t\t\tconst firstLine = body.split(\"\\n\").find((line) => line.trim());\n\t\t\tif (firstLine) description = firstLine.length > 60 ? `${firstLine.slice(0, 60)}...` : firstLine;\n\t\t}\n\t\treturn {\n\t\t\tname,\n\t\t\tdescription,\n\t\t\t...(frontmatter[\"argument-hint\"] && { argumentHint: frontmatter[\"argument-hint\"] }),\n\t\t\tcontent: body,\n\t\t\tsourceInfo,\n\t\t\tfilePath,\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function loadTemplatesFromDir(\n\tdir: string,\n\tgetSourceInfo: (filePath: string) => Promise<SourceInfo>,\n): Promise<PromptTemplate[]> {\n\tconst templates: PromptTemplate[] = [];\n\tif (!(await exists(dir))) return templates;\n\tconst startedAt = Date.now();\n\ttry {\n\t\tconst entries = await readdir(dir, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\tawait yieldToEventLoopIfSlow(startedAt, YIELD_AFTER_MS);\n\t\t\tconst fullPath = join(dir, entry.name);\n\t\t\tlet isFile = entry.isFile();\n\t\t\tif (entry.isSymbolicLink()) {\n\t\t\t\ttry { isFile = (await stat(fullPath)).isFile(); } catch { continue; }\n\t\t\t}\n\t\t\tif (!isFile || !entry.name.endsWith(\".md\")) continue;\n\t\t\tconst template = await loadTemplateFromFile(fullPath, await getSourceInfo(fullPath));\n\t\t\tif (template) templates.push(template);\n\t\t}\n\t} catch {}\n\treturn templates;\n}\n\nexport async function loadPromptTemplatesAsync(options: LoadPromptTemplatesOptions): Promise<PromptTemplate[]> {\n\tconst resolvedCwd = resolvePath(options.cwd);\n\tconst resolvedAgentDir = resolvePath(options.agentDir);\n\tconst promptPaths = options.promptPaths ?? [];\n\tconst includeDefaults = options.includeDefaults ?? true;\n\tconst templates: PromptTemplate[] = [];\n\tconst globalPromptsDir = join(resolvedAgentDir, \"prompts\");\n\tconst projectPromptsDir = resolve(resolvedCwd, CONFIG_DIR_NAME, \"prompts\");\n\tconst isUnderPath = (target: string, root: string): boolean => {\n\t\tconst normalizedRoot = resolve(root);\n\t\treturn target === normalizedRoot || target.startsWith(normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`);\n\t};\n\tconst getSourceInfo = async (resolvedPath: string): Promise<SourceInfo> => {\n\t\tif (isUnderPath(resolvedPath, globalPromptsDir)) {\n\t\t\treturn createSyntheticSourceInfo(resolvedPath, { source: \"local\", scope: \"user\", baseDir: globalPromptsDir });\n\t\t}\n\t\tif (isUnderPath(resolvedPath, projectPromptsDir)) {\n\t\t\treturn createSyntheticSourceInfo(resolvedPath, { source: \"local\", scope: \"project\", baseDir: projectPromptsDir });\n\t\t}\n\t\tconst stats = await stat(resolvedPath);\n\t\treturn createSyntheticSourceInfo(resolvedPath, { source: \"local\", baseDir: stats.isDirectory() ? resolvedPath : dirname(resolvedPath) });\n\t};\n\tif (includeDefaults) {\n\t\ttemplates.push(...await loadTemplatesFromDir(globalPromptsDir, getSourceInfo));\n\t\ttemplates.push(...await loadTemplatesFromDir(projectPromptsDir, getSourceInfo));\n\t}\n\tconst startedAt = Date.now();\n\tfor (const rawPath of promptPaths) {\n\t\tawait yieldToEventLoopIfSlow(startedAt, YIELD_AFTER_MS);\n\t\tconst resolvedPath = resolvePath(rawPath, resolvedCwd, { trim: true });\n\t\tif (!(await exists(resolvedPath))) continue;\n\t\ttry {\n\t\t\tconst stats = await stat(resolvedPath);\n\t\t\tif (stats.isDirectory()) {\n\t\t\t\ttemplates.push(...await loadTemplatesFromDir(resolvedPath, getSourceInfo));\n\t\t\t} else if (stats.isFile() && resolvedPath.endsWith(\".md\")) {\n\t\t\t\tconst template = await loadTemplateFromFile(resolvedPath, await getSourceInfo(resolvedPath));\n\t\t\t\tif (template) templates.push(template);\n\t\t\t}\n\t\t} catch {}\n\t}\n\treturn templates;\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import type { AgentMessage } from "@earendil-works/pi-agent-core";
2
+ import type { SessionEntry } from "./session-manager.ts";
3
+ /**
4
+ * Provider-side token-budget estimators use the last assistant usage in the
5
+ * request context as an anchor. After logical context compaction, retained
6
+ * pre-compaction assistant messages still carry usage from the old, larger
7
+ * context. Scrub only the provider-bound clone so the durable transcript keeps
8
+ * historical billing data while the next request estimates the compacted prompt.
9
+ */
10
+ export declare function scrubPreCompactionAssistantUsage(messages: AgentMessage[], entries: readonly SessionEntry[]): AgentMessage[];
11
+ //# sourceMappingURL=provider-context-usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-context-usage.d.ts","sourceRoot":"","sources":["../../src/core/provider-context-usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE,OAAO,KAAK,EAA0B,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAqCjF;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC/C,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,EAAE,SAAS,YAAY,EAAE,GAC9B,YAAY,EAAE,CAqBhB","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { AssistantMessage, Usage } from \"@earendil-works/pi-ai/compat\";\nimport type { ContextCompactionEntry, SessionEntry } from \"./session-manager.ts\";\n\nfunction findLatestCompactionBoundary(entries: readonly SessionEntry[]): ContextCompactionEntry | undefined {\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tif (entry.type === \"context_compaction\") {\n\t\t\treturn entry;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction hasTokenUsage(usage: Usage): boolean {\n\treturn usage.input > 0 || usage.output > 0 || usage.cacheRead > 0 || usage.cacheWrite > 0 || usage.totalTokens > 0;\n}\n\nfunction createZeroUsage(usage: Usage): Usage {\n\tconst zeroed: Usage = {\n\t\t...usage,\n\t\tinput: 0,\n\t\toutput: 0,\n\t\tcacheRead: 0,\n\t\tcacheWrite: 0,\n\t\ttotalTokens: 0,\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t};\n\n\tif (usage.cacheWrite1h !== undefined) {\n\t\tzeroed.cacheWrite1h = 0;\n\t}\n\tif (usage.reasoning !== undefined) {\n\t\tzeroed.reasoning = 0;\n\t}\n\n\treturn zeroed;\n}\n\n/**\n * Provider-side token-budget estimators use the last assistant usage in the\n * request context as an anchor. After logical context compaction, retained\n * pre-compaction assistant messages still carry usage from the old, larger\n * context. Scrub only the provider-bound clone so the durable transcript keeps\n * historical billing data while the next request estimates the compacted prompt.\n */\nexport function scrubPreCompactionAssistantUsage(\n\tmessages: AgentMessage[],\n\tentries: readonly SessionEntry[],\n): AgentMessage[] {\n\tconst compactionBoundary = findLatestCompactionBoundary(entries);\n\tif (!compactionBoundary) return messages;\n\n\tconst boundaryTime = Date.parse(compactionBoundary.timestamp);\n\tif (!Number.isFinite(boundaryTime)) return messages;\n\n\tlet changed = false;\n\tconst scrubbed = messages.map((message) => {\n\t\tif (message.role !== \"assistant\") return message;\n\n\t\tconst assistant = message as AssistantMessage;\n\t\tif (assistant.timestamp > boundaryTime || !hasTokenUsage(assistant.usage)) {\n\t\t\treturn message;\n\t\t}\n\n\t\tchanged = true;\n\t\treturn { ...assistant, usage: createZeroUsage(assistant.usage) };\n\t});\n\n\treturn changed ? scrubbed : messages;\n}\n"]}