@vaclav-synacek/pi-coding-agent-termux 0.50.3-0 → 0.50.7-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +52 -1
  2. package/dist/core/agent-session.d.ts +8 -0
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +15 -0
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/extensions/runner.d.ts +1 -0
  7. package/dist/core/extensions/runner.d.ts.map +1 -1
  8. package/dist/core/extensions/runner.js +3 -0
  9. package/dist/core/extensions/runner.js.map +1 -1
  10. package/dist/core/extensions/types.d.ts +3 -0
  11. package/dist/core/extensions/types.d.ts.map +1 -1
  12. package/dist/core/extensions/types.js.map +1 -1
  13. package/dist/core/model-registry.d.ts.map +1 -1
  14. package/dist/core/model-registry.js +6 -0
  15. package/dist/core/model-registry.js.map +1 -1
  16. package/dist/core/package-manager.d.ts.map +1 -1
  17. package/dist/core/package-manager.js +98 -16
  18. package/dist/core/package-manager.js.map +1 -1
  19. package/dist/core/settings-manager.d.ts +4 -3
  20. package/dist/core/settings-manager.d.ts.map +1 -1
  21. package/dist/core/settings-manager.js +25 -12
  22. package/dist/core/settings-manager.js.map +1 -1
  23. package/dist/core/tools/path-utils.d.ts.map +1 -1
  24. package/dist/core/tools/path-utils.js +28 -3
  25. package/dist/core/tools/path-utils.js.map +1 -1
  26. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  27. package/dist/modes/interactive/components/config-selector.js +12 -1
  28. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  29. package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  30. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
  31. package/dist/modes/interactive/components/daxnuts.js +140 -0
  32. package/dist/modes/interactive/components/daxnuts.js.map +1 -0
  33. package/dist/modes/interactive/components/index.d.ts +1 -0
  34. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  35. package/dist/modes/interactive/components/index.js +1 -0
  36. package/dist/modes/interactive/components/index.js.map +1 -1
  37. package/dist/modes/interactive/components/settings-selector.d.ts +2 -2
  38. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  39. package/dist/modes/interactive/components/settings-selector.js +1 -1
  40. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  41. package/dist/modes/interactive/interactive-mode.d.ts +2 -0
  42. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  43. package/dist/modes/interactive/interactive-mode.js +31 -10
  44. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  45. package/dist/modes/rpc/rpc-client.d.ts +4 -0
  46. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  47. package/dist/modes/rpc/rpc-client.js +6 -0
  48. package/dist/modes/rpc/rpc-client.js.map +1 -1
  49. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  50. package/dist/modes/rpc/rpc-mode.js +9 -0
  51. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  52. package/dist/modes/rpc/rpc-types.d.ts +10 -0
  53. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  54. package/dist/modes/rpc/rpc-types.js.map +1 -1
  55. package/dist/utils/clipboard.d.ts.map +1 -1
  56. package/dist/utils/clipboard.js +4 -0
  57. package/dist/utils/clipboard.js.map +1 -1
  58. package/docs/extensions.md +12 -0
  59. package/docs/keybindings.md +4 -2
  60. package/docs/models.md +32 -0
  61. package/docs/providers.md +2 -1
  62. package/docs/rpc.md +21 -1
  63. package/examples/extensions/antigravity-image-gen.ts +1 -1
  64. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  65. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  66. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  67. package/examples/extensions/system-prompt-header.ts +17 -0
  68. package/examples/extensions/with-deps/package-lock.json +2 -2
  69. package/examples/extensions/with-deps/package.json +1 -1
  70. package/package.json +5 -4
@@ -2,7 +2,8 @@ import { spawn, spawnSync } from "node:child_process";
2
2
  import { createHash } from "node:crypto";
3
3
  import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
4
4
  import { homedir, tmpdir } from "node:os";
5
- import { basename, dirname, join, relative, resolve } from "node:path";
5
+ import { basename, dirname, join, relative, resolve, sep } from "node:path";
6
+ import ignore from "ignore";
6
7
  import { minimatch } from "minimatch";
7
8
  import { CONFIG_DIR_NAME } from "../config.js";
8
9
  import { looksLikeGitUrl } from "../utils/git.js";
@@ -13,6 +14,51 @@ const FILE_PATTERNS = {
13
14
  prompts: /\.md$/,
14
15
  themes: /\.json$/,
15
16
  };
17
+ const IGNORE_FILE_NAMES = [".gitignore", ".ignore", ".fdignore"];
18
+ function toPosixPath(p) {
19
+ return p.split(sep).join("/");
20
+ }
21
+ function prefixIgnorePattern(line, prefix) {
22
+ const trimmed = line.trim();
23
+ if (!trimmed)
24
+ return null;
25
+ if (trimmed.startsWith("#") && !trimmed.startsWith("\\#"))
26
+ return null;
27
+ let pattern = line;
28
+ let negated = false;
29
+ if (pattern.startsWith("!")) {
30
+ negated = true;
31
+ pattern = pattern.slice(1);
32
+ }
33
+ else if (pattern.startsWith("\\!")) {
34
+ pattern = pattern.slice(1);
35
+ }
36
+ if (pattern.startsWith("/")) {
37
+ pattern = pattern.slice(1);
38
+ }
39
+ const prefixed = prefix ? `${prefix}${pattern}` : pattern;
40
+ return negated ? `!${prefixed}` : prefixed;
41
+ }
42
+ function addIgnoreRules(ig, dir, rootDir) {
43
+ const relativeDir = relative(rootDir, dir);
44
+ const prefix = relativeDir ? `${toPosixPath(relativeDir)}/` : "";
45
+ for (const filename of IGNORE_FILE_NAMES) {
46
+ const ignorePath = join(dir, filename);
47
+ if (!existsSync(ignorePath))
48
+ continue;
49
+ try {
50
+ const content = readFileSync(ignorePath, "utf-8");
51
+ const patterns = content
52
+ .split(/\r?\n/)
53
+ .map((line) => prefixIgnorePattern(line, prefix))
54
+ .filter((line) => Boolean(line));
55
+ if (patterns.length > 0) {
56
+ ig.add(patterns);
57
+ }
58
+ }
59
+ catch { }
60
+ }
61
+ }
16
62
  function isPattern(s) {
17
63
  return s.startsWith("!") || s.startsWith("+") || s.startsWith("-") || s.includes("*") || s.includes("?");
18
64
  }
@@ -29,10 +75,13 @@ function splitPatterns(entries) {
29
75
  }
30
76
  return { plain, patterns };
31
77
  }
32
- function collectFiles(dir, filePattern, skipNodeModules = true) {
78
+ function collectFiles(dir, filePattern, skipNodeModules = true, ignoreMatcher, rootDir) {
33
79
  const files = [];
34
80
  if (!existsSync(dir))
35
81
  return files;
82
+ const root = rootDir ?? dir;
83
+ const ig = ignoreMatcher ?? ignore();
84
+ addIgnoreRules(ig, dir, root);
36
85
  try {
37
86
  const entries = readdirSync(dir, { withFileTypes: true });
38
87
  for (const entry of entries) {
@@ -53,8 +102,12 @@ function collectFiles(dir, filePattern, skipNodeModules = true) {
53
102
  continue;
54
103
  }
55
104
  }
105
+ const relPath = toPosixPath(relative(root, fullPath));
106
+ const ignorePath = isDir ? `${relPath}/` : relPath;
107
+ if (ig.ignores(ignorePath))
108
+ continue;
56
109
  if (isDir) {
57
- files.push(...collectFiles(fullPath, filePattern, skipNodeModules));
110
+ files.push(...collectFiles(fullPath, filePattern, skipNodeModules, ig, root));
58
111
  }
59
112
  else if (isFile && filePattern.test(entry.name)) {
60
113
  files.push(fullPath);
@@ -66,10 +119,13 @@ function collectFiles(dir, filePattern, skipNodeModules = true) {
66
119
  }
67
120
  return files;
68
121
  }
69
- function collectSkillEntries(dir, includeRootFiles = true) {
122
+ function collectSkillEntries(dir, includeRootFiles = true, ignoreMatcher, rootDir) {
70
123
  const entries = [];
71
124
  if (!existsSync(dir))
72
125
  return entries;
126
+ const root = rootDir ?? dir;
127
+ const ig = ignoreMatcher ?? ignore();
128
+ addIgnoreRules(ig, dir, root);
73
129
  try {
74
130
  const dirEntries = readdirSync(dir, { withFileTypes: true });
75
131
  for (const entry of dirEntries) {
@@ -90,8 +146,12 @@ function collectSkillEntries(dir, includeRootFiles = true) {
90
146
  continue;
91
147
  }
92
148
  }
149
+ const relPath = toPosixPath(relative(root, fullPath));
150
+ const ignorePath = isDir ? `${relPath}/` : relPath;
151
+ if (ig.ignores(ignorePath))
152
+ continue;
93
153
  if (isDir) {
94
- entries.push(...collectSkillEntries(fullPath, false));
154
+ entries.push(...collectSkillEntries(fullPath, false, ig, root));
95
155
  }
96
156
  else if (isFile) {
97
157
  const isRootMd = includeRootFiles && entry.name.endsWith(".md");
@@ -114,6 +174,8 @@ function collectAutoPromptEntries(dir) {
114
174
  const entries = [];
115
175
  if (!existsSync(dir))
116
176
  return entries;
177
+ const ig = ignore();
178
+ addIgnoreRules(ig, dir, dir);
117
179
  try {
118
180
  const dirEntries = readdirSync(dir, { withFileTypes: true });
119
181
  for (const entry of dirEntries) {
@@ -131,6 +193,9 @@ function collectAutoPromptEntries(dir) {
131
193
  continue;
132
194
  }
133
195
  }
196
+ const relPath = toPosixPath(relative(dir, fullPath));
197
+ if (ig.ignores(relPath))
198
+ continue;
134
199
  if (isFile && entry.name.endsWith(".md")) {
135
200
  entries.push(fullPath);
136
201
  }
@@ -145,6 +210,8 @@ function collectAutoThemeEntries(dir) {
145
210
  const entries = [];
146
211
  if (!existsSync(dir))
147
212
  return entries;
213
+ const ig = ignore();
214
+ addIgnoreRules(ig, dir, dir);
148
215
  try {
149
216
  const dirEntries = readdirSync(dir, { withFileTypes: true });
150
217
  for (const entry of dirEntries) {
@@ -162,6 +229,9 @@ function collectAutoThemeEntries(dir) {
162
229
  continue;
163
230
  }
164
231
  }
232
+ const relPath = toPosixPath(relative(dir, fullPath));
233
+ if (ig.ignores(relPath))
234
+ continue;
165
235
  if (isFile && entry.name.endsWith(".json")) {
166
236
  entries.push(fullPath);
167
237
  }
@@ -213,6 +283,8 @@ function collectAutoExtensionEntries(dir) {
213
283
  const entries = [];
214
284
  if (!existsSync(dir))
215
285
  return entries;
286
+ const ig = ignore();
287
+ addIgnoreRules(ig, dir, dir);
216
288
  try {
217
289
  const dirEntries = readdirSync(dir, { withFileTypes: true });
218
290
  for (const entry of dirEntries) {
@@ -233,6 +305,10 @@ function collectAutoExtensionEntries(dir) {
233
305
  continue;
234
306
  }
235
307
  }
308
+ const relPath = toPosixPath(relative(dir, fullPath));
309
+ const ignorePath = isDir ? `${relPath}/` : relPath;
310
+ if (ig.ignores(ignorePath))
311
+ continue;
236
312
  if (isFile && (entry.name.endsWith(".ts") || entry.name.endsWith(".js"))) {
237
313
  entries.push(fullPath);
238
314
  }
@@ -249,6 +325,19 @@ function collectAutoExtensionEntries(dir) {
249
325
  }
250
326
  return entries;
251
327
  }
328
+ /**
329
+ * Collect resource files from a directory based on resource type.
330
+ * Extensions use smart discovery (index.ts in subdirs), others use recursive collection.
331
+ */
332
+ function collectResourceFiles(dir, resourceType) {
333
+ if (resourceType === "skills") {
334
+ return collectSkillEntries(dir);
335
+ }
336
+ if (resourceType === "extensions") {
337
+ return collectAutoExtensionEntries(dir);
338
+ }
339
+ return collectFiles(dir, FILE_PATTERNS[resourceType]);
340
+ }
252
341
  function matchesAnyPattern(filePath, patterns, baseDir) {
253
342
  const rel = relative(baseDir, filePath);
254
343
  const name = basename(filePath);
@@ -918,7 +1007,7 @@ export class DefaultPackageManager {
918
1007
  const dir = join(packageRoot, resourceType);
919
1008
  if (existsSync(dir)) {
920
1009
  // Collect all files from the directory (all enabled by default)
921
- const files = resourceType === "skills" ? collectSkillEntries(dir) : collectFiles(dir, FILE_PATTERNS[resourceType]);
1010
+ const files = collectResourceFiles(dir, resourceType);
922
1011
  for (const f of files) {
923
1012
  this.addResource(this.getTargetMap(accumulator, resourceType), f, metadata, true);
924
1013
  }
@@ -937,7 +1026,7 @@ export class DefaultPackageManager {
937
1026
  const dir = join(packageRoot, resourceType);
938
1027
  if (existsSync(dir)) {
939
1028
  // Collect all files from the directory (all enabled by default)
940
- const files = resourceType === "skills" ? collectSkillEntries(dir) : collectFiles(dir, FILE_PATTERNS[resourceType]);
1029
+ const files = collectResourceFiles(dir, resourceType);
941
1030
  for (const f of files) {
942
1031
  this.addResource(target, f, metadata, true);
943
1032
  }
@@ -977,9 +1066,7 @@ export class DefaultPackageManager {
977
1066
  if (!existsSync(conventionDir)) {
978
1067
  return { allFiles: [], enabledByManifest: new Set() };
979
1068
  }
980
- const allFiles = resourceType === "skills"
981
- ? collectSkillEntries(conventionDir)
982
- : collectFiles(conventionDir, FILE_PATTERNS[resourceType]);
1069
+ const allFiles = collectResourceFiles(conventionDir, resourceType);
983
1070
  return { allFiles, enabledByManifest: new Set(allFiles) };
984
1071
  }
985
1072
  readPiManifest(packageRoot) {
@@ -1091,12 +1178,7 @@ export class DefaultPackageManager {
1091
1178
  files.push(p);
1092
1179
  }
1093
1180
  else if (stats.isDirectory()) {
1094
- if (resourceType === "skills") {
1095
- files.push(...collectSkillEntries(p));
1096
- }
1097
- else {
1098
- files.push(...collectFiles(p, FILE_PATTERNS[resourceType]));
1099
- }
1181
+ files.push(...collectResourceFiles(p, resourceType));
1100
1182
  }
1101
1183
  }
1102
1184
  catch {