@fleetagent/pi-coding-agent 0.0.4 → 0.0.6

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 (95) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +28 -5
  3. package/dist/cli/args.d.ts +2 -0
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +9 -0
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/core/agent-session.d.ts +4 -3
  8. package/dist/core/agent-session.d.ts.map +1 -1
  9. package/dist/core/agent-session.js +44 -8
  10. package/dist/core/agent-session.js.map +1 -1
  11. package/dist/core/diagnostics.d.ts +1 -1
  12. package/dist/core/diagnostics.d.ts.map +1 -1
  13. package/dist/core/diagnostics.js.map +1 -1
  14. package/dist/core/extensions/runner.d.ts +4 -0
  15. package/dist/core/extensions/runner.d.ts.map +1 -1
  16. package/dist/core/extensions/runner.js +5 -1
  17. package/dist/core/extensions/runner.js.map +1 -1
  18. package/dist/core/extensions/types.d.ts +2 -1
  19. package/dist/core/extensions/types.d.ts.map +1 -1
  20. package/dist/core/extensions/types.js.map +1 -1
  21. package/dist/core/package-manager.d.ts +1 -0
  22. package/dist/core/package-manager.d.ts.map +1 -1
  23. package/dist/core/package-manager.js +130 -12
  24. package/dist/core/package-manager.js.map +1 -1
  25. package/dist/core/resource-loader.d.ts +30 -0
  26. package/dist/core/resource-loader.d.ts.map +1 -1
  27. package/dist/core/resource-loader.js +94 -0
  28. package/dist/core/resource-loader.js.map +1 -1
  29. package/dist/core/rules.d.ts +57 -0
  30. package/dist/core/rules.d.ts.map +1 -0
  31. package/dist/core/rules.js +384 -0
  32. package/dist/core/rules.js.map +1 -0
  33. package/dist/core/settings-manager.d.ts +5 -0
  34. package/dist/core/settings-manager.d.ts.map +1 -1
  35. package/dist/core/settings-manager.js +14 -0
  36. package/dist/core/settings-manager.js.map +1 -1
  37. package/dist/core/slash-commands.d.ts +1 -1
  38. package/dist/core/slash-commands.d.ts.map +1 -1
  39. package/dist/core/slash-commands.js +1 -1
  40. package/dist/core/slash-commands.js.map +1 -1
  41. package/dist/core/system-prompt.d.ts +3 -0
  42. package/dist/core/system-prompt.d.ts.map +1 -1
  43. package/dist/core/system-prompt.js +11 -3
  44. package/dist/core/system-prompt.js.map +1 -1
  45. package/dist/core/tools/read.d.ts.map +1 -1
  46. package/dist/core/tools/read.js +6 -2
  47. package/dist/core/tools/read.js.map +1 -1
  48. package/dist/index.d.ts +1 -0
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +2 -0
  51. package/dist/index.js.map +1 -1
  52. package/dist/main.d.ts.map +1 -1
  53. package/dist/main.js +3 -0
  54. package/dist/main.js.map +1 -1
  55. package/dist/modes/interactive/components/config-selector.d.ts +1 -1
  56. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  57. package/dist/modes/interactive/components/config-selector.js +12 -3
  58. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  59. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  60. package/dist/modes/interactive/components/settings-selector.js +1 -1
  61. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  62. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  63. package/dist/modes/interactive/interactive-mode.js +34 -4
  64. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  65. package/dist/modes/rpc/rpc-client.d.ts +14 -1
  66. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  67. package/dist/modes/rpc/rpc-client.js +34 -11
  68. package/dist/modes/rpc/rpc-client.js.map +1 -1
  69. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  70. package/dist/modes/rpc/rpc-mode.js +18 -0
  71. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  72. package/dist/modes/rpc/rpc-types.d.ts +17 -2
  73. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  74. package/dist/modes/rpc/rpc-types.js.map +1 -1
  75. package/docs/extensions.md +9 -8
  76. package/docs/index.md +3 -2
  77. package/docs/packages.md +6 -4
  78. package/docs/quickstart.md +1 -1
  79. package/docs/rpc.md +4 -2
  80. package/docs/rules.md +102 -0
  81. package/docs/sdk.md +1 -1
  82. package/docs/settings.md +3 -2
  83. package/docs/usage.md +4 -2
  84. package/examples/extensions/README.md +1 -1
  85. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  86. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  87. package/examples/extensions/dynamic-resources/RULES.md +8 -0
  88. package/examples/extensions/dynamic-resources/index.ts +1 -0
  89. package/examples/extensions/reload-runtime.ts +2 -2
  90. package/examples/extensions/sandbox/package.json +1 -1
  91. package/examples/extensions/with-deps/package.json +1 -1
  92. package/examples/sdk/12-full-control.ts +1 -0
  93. package/examples/sdk/README.md +1 -1
  94. package/npm-shrinkwrap.json +12 -12
  95. package/package.json +4 -4
@@ -56,10 +56,11 @@ function resourcePrecedenceRank(m) {
56
56
  const scopeBase = m.scope === "project" ? 0 : 2;
57
57
  return scopeBase + (m.source === "local" ? 0 : 1);
58
58
  }
59
- const RESOURCE_TYPES = ["extensions", "skills", "prompts", "themes"];
59
+ const RESOURCE_TYPES = ["extensions", "skills", "rules", "prompts", "themes"];
60
60
  const FILE_PATTERNS = {
61
61
  extensions: /\.(ts|js)$/,
62
62
  skills: /\.md$/,
63
+ rules: /\.md$/,
63
64
  prompts: /\.md$/,
64
65
  themes: /\.json$/,
65
66
  };
@@ -244,6 +245,72 @@ function collectSkillEntries(dir, mode, ignoreMatcher, rootDir) {
244
245
  function collectAutoSkillEntries(dir, mode) {
245
246
  return collectSkillEntries(dir, mode);
246
247
  }
248
+ function collectRuleEntries(dir, mode, ignoreMatcher, rootDir) {
249
+ const entries = [];
250
+ if (!existsSync(dir))
251
+ return entries;
252
+ const root = rootDir ?? dir;
253
+ const ig = ignoreMatcher ?? ignore();
254
+ addIgnoreRules(ig, dir, root);
255
+ try {
256
+ const dirEntries = readdirSync(dir, { withFileTypes: true });
257
+ for (const entry of dirEntries) {
258
+ if (entry.name !== "RULES.md")
259
+ continue;
260
+ const fullPath = join(dir, entry.name);
261
+ let isFile = entry.isFile();
262
+ if (entry.isSymbolicLink()) {
263
+ try {
264
+ isFile = statSync(fullPath).isFile();
265
+ }
266
+ catch {
267
+ continue;
268
+ }
269
+ }
270
+ const relPath = toPosixPath(relative(root, fullPath));
271
+ if (isFile && !ig.ignores(relPath)) {
272
+ entries.push(fullPath);
273
+ return entries;
274
+ }
275
+ }
276
+ for (const entry of dirEntries) {
277
+ if (entry.name.startsWith("."))
278
+ continue;
279
+ if (entry.name === "node_modules")
280
+ continue;
281
+ const fullPath = join(dir, entry.name);
282
+ let isDir = entry.isDirectory();
283
+ let isFile = entry.isFile();
284
+ if (entry.isSymbolicLink()) {
285
+ try {
286
+ const stats = statSync(fullPath);
287
+ isDir = stats.isDirectory();
288
+ isFile = stats.isFile();
289
+ }
290
+ catch {
291
+ continue;
292
+ }
293
+ }
294
+ const relPath = toPosixPath(relative(root, fullPath));
295
+ if (mode === "pi" && dir === root && isFile && entry.name.endsWith(".md") && !ig.ignores(relPath)) {
296
+ entries.push(fullPath);
297
+ continue;
298
+ }
299
+ if (!isDir)
300
+ continue;
301
+ if (ig.ignores(`${relPath}/`))
302
+ continue;
303
+ entries.push(...collectRuleEntries(fullPath, mode, ig, root));
304
+ }
305
+ }
306
+ catch {
307
+ // Ignore errors
308
+ }
309
+ return entries;
310
+ }
311
+ function collectAutoRuleEntries(dir, mode) {
312
+ return collectRuleEntries(dir, mode);
313
+ }
247
314
  function findGitRepoRoot(startDir) {
248
315
  let dir = resolve(startDir);
249
316
  while (true) {
@@ -275,6 +342,24 @@ function collectAncestorAgentsSkillDirs(startDir) {
275
342
  }
276
343
  return skillDirs;
277
344
  }
345
+ function collectAncestorAgentsRuleDirs(startDir) {
346
+ const ruleDirs = [];
347
+ const resolvedStartDir = resolve(startDir);
348
+ const gitRepoRoot = findGitRepoRoot(resolvedStartDir);
349
+ let dir = resolvedStartDir;
350
+ while (true) {
351
+ ruleDirs.push(join(dir, ".agents", "rules"));
352
+ if (gitRepoRoot && dir === gitRepoRoot) {
353
+ break;
354
+ }
355
+ const parent = dirname(dir);
356
+ if (parent === dir) {
357
+ break;
358
+ }
359
+ dir = parent;
360
+ }
361
+ return ruleDirs;
362
+ }
278
363
  function collectAutoPromptEntries(dir) {
279
364
  const entries = [];
280
365
  if (!existsSync(dir))
@@ -444,6 +529,9 @@ function collectResourceFiles(dir, resourceType) {
444
529
  if (resourceType === "skills") {
445
530
  return collectSkillEntries(dir, "pi");
446
531
  }
532
+ if (resourceType === "rules") {
533
+ return collectRuleEntries(dir, "pi");
534
+ }
447
535
  if (resourceType === "extensions") {
448
536
  return collectAutoExtensionEntries(dir);
449
537
  }
@@ -453,11 +541,11 @@ function matchesAnyPattern(filePath, patterns, baseDir) {
453
541
  const rel = toPosixPath(relative(baseDir, filePath));
454
542
  const name = basename(filePath);
455
543
  const filePathPosix = toPosixPath(filePath);
456
- const isSkillFile = name === "SKILL.md";
457
- const parentDir = isSkillFile ? dirname(filePath) : undefined;
458
- const parentRel = isSkillFile ? toPosixPath(relative(baseDir, parentDir)) : undefined;
459
- const parentName = isSkillFile ? basename(parentDir) : undefined;
460
- const parentDirPosix = isSkillFile ? toPosixPath(parentDir) : undefined;
544
+ const isDirectoryResourceFile = name === "SKILL.md" || name === "RULES.md";
545
+ const parentDir = isDirectoryResourceFile ? dirname(filePath) : undefined;
546
+ const parentRel = isDirectoryResourceFile ? toPosixPath(relative(baseDir, parentDir)) : undefined;
547
+ const parentName = isDirectoryResourceFile ? basename(parentDir) : undefined;
548
+ const parentDirPosix = isDirectoryResourceFile ? toPosixPath(parentDir) : undefined;
461
549
  return patterns.some((pattern) => {
462
550
  const normalizedPattern = toPosixPath(pattern);
463
551
  if (minimatch(rel, normalizedPattern) ||
@@ -465,7 +553,7 @@ function matchesAnyPattern(filePath, patterns, baseDir) {
465
553
  minimatch(filePathPosix, normalizedPattern)) {
466
554
  return true;
467
555
  }
468
- if (!isSkillFile)
556
+ if (!isDirectoryResourceFile)
469
557
  return false;
470
558
  return (minimatch(parentRel, normalizedPattern) ||
471
559
  minimatch(parentName, normalizedPattern) ||
@@ -482,16 +570,16 @@ function matchesAnyExactPattern(filePath, patterns, baseDir) {
482
570
  const rel = toPosixPath(relative(baseDir, filePath));
483
571
  const name = basename(filePath);
484
572
  const filePathPosix = toPosixPath(filePath);
485
- const isSkillFile = name === "SKILL.md";
486
- const parentDir = isSkillFile ? dirname(filePath) : undefined;
487
- const parentRel = isSkillFile ? toPosixPath(relative(baseDir, parentDir)) : undefined;
488
- const parentDirPosix = isSkillFile ? toPosixPath(parentDir) : undefined;
573
+ const isDirectoryResourceFile = name === "SKILL.md" || name === "RULES.md";
574
+ const parentDir = isDirectoryResourceFile ? dirname(filePath) : undefined;
575
+ const parentRel = isDirectoryResourceFile ? toPosixPath(relative(baseDir, parentDir)) : undefined;
576
+ const parentDirPosix = isDirectoryResourceFile ? toPosixPath(parentDir) : undefined;
489
577
  return patterns.some((pattern) => {
490
578
  const normalized = normalizeExactPattern(pattern);
491
579
  if (normalized === rel || normalized === filePathPosix) {
492
580
  return true;
493
581
  }
494
- if (!isSkillFile)
582
+ if (!isDirectoryResourceFile)
495
583
  return false;
496
584
  return normalized === parentRel || normalized === parentDirPosix;
497
585
  });
@@ -1803,29 +1891,35 @@ export class DefaultPackageManager {
1803
1891
  const userOverrides = {
1804
1892
  extensions: (globalSettings.extensions ?? []),
1805
1893
  skills: (globalSettings.skills ?? []),
1894
+ rules: (globalSettings.rules ?? []),
1806
1895
  prompts: (globalSettings.prompts ?? []),
1807
1896
  themes: (globalSettings.themes ?? []),
1808
1897
  };
1809
1898
  const projectOverrides = {
1810
1899
  extensions: (projectSettings.extensions ?? []),
1811
1900
  skills: (projectSettings.skills ?? []),
1901
+ rules: (projectSettings.rules ?? []),
1812
1902
  prompts: (projectSettings.prompts ?? []),
1813
1903
  themes: (projectSettings.themes ?? []),
1814
1904
  };
1815
1905
  const userDirs = {
1816
1906
  extensions: join(globalBaseDir, "extensions"),
1817
1907
  skills: join(globalBaseDir, "skills"),
1908
+ rules: join(globalBaseDir, "rules"),
1818
1909
  prompts: join(globalBaseDir, "prompts"),
1819
1910
  themes: join(globalBaseDir, "themes"),
1820
1911
  };
1821
1912
  const projectDirs = {
1822
1913
  extensions: join(projectBaseDir, "extensions"),
1823
1914
  skills: join(projectBaseDir, "skills"),
1915
+ rules: join(projectBaseDir, "rules"),
1824
1916
  prompts: join(projectBaseDir, "prompts"),
1825
1917
  themes: join(projectBaseDir, "themes"),
1826
1918
  };
1827
1919
  const userAgentsSkillsDir = join(getHomeDir(), ".agents", "skills");
1920
+ const userAgentsRulesDir = join(getHomeDir(), ".agents", "rules");
1828
1921
  const projectAgentsSkillDirs = collectAncestorAgentsSkillDirs(this.cwd).filter((dir) => resolve(dir) !== resolve(userAgentsSkillsDir));
1922
+ const projectAgentsRuleDirs = collectAncestorAgentsRuleDirs(this.cwd).filter((dir) => resolve(dir) !== resolve(userAgentsRulesDir));
1829
1923
  const addResources = (resourceType, paths, metadata, overrides, baseDir) => {
1830
1924
  const target = this.getTargetMap(accumulator, resourceType);
1831
1925
  for (const path of paths) {
@@ -1837,6 +1931,8 @@ export class DefaultPackageManager {
1837
1931
  addResources("extensions", collectAutoExtensionEntries(projectDirs.extensions), projectMetadata, projectOverrides.extensions, projectBaseDir);
1838
1932
  // Project skills from .pi/
1839
1933
  addResources("skills", collectAutoSkillEntries(projectDirs.skills, "pi"), projectMetadata, projectOverrides.skills, projectBaseDir);
1934
+ // Project rules from .pi/
1935
+ addResources("rules", collectAutoRuleEntries(projectDirs.rules, "pi"), projectMetadata, projectOverrides.rules, projectBaseDir);
1840
1936
  // Project skills from .agents/ (each with its own baseDir)
1841
1937
  for (const agentsSkillsDir of projectAgentsSkillDirs) {
1842
1938
  const agentsBaseDir = dirname(agentsSkillsDir); // the .agents directory
@@ -1846,12 +1942,23 @@ export class DefaultPackageManager {
1846
1942
  };
1847
1943
  addResources("skills", collectAutoSkillEntries(agentsSkillsDir, "agents"), agentsMetadata, projectOverrides.skills, agentsBaseDir);
1848
1944
  }
1945
+ // Project rules from .agents/ (each with its own baseDir)
1946
+ for (const agentsRulesDir of projectAgentsRuleDirs) {
1947
+ const agentsBaseDir = dirname(agentsRulesDir); // the .agents directory
1948
+ const agentsMetadata = {
1949
+ ...projectMetadata,
1950
+ baseDir: agentsBaseDir,
1951
+ };
1952
+ addResources("rules", collectAutoRuleEntries(agentsRulesDir, "agents"), agentsMetadata, projectOverrides.rules, agentsBaseDir);
1953
+ }
1849
1954
  addResources("prompts", collectAutoPromptEntries(projectDirs.prompts), projectMetadata, projectOverrides.prompts, projectBaseDir);
1850
1955
  addResources("themes", collectAutoThemeEntries(projectDirs.themes), projectMetadata, projectOverrides.themes, projectBaseDir);
1851
1956
  // User extensions from ~/.pi/agent/
1852
1957
  addResources("extensions", collectAutoExtensionEntries(userDirs.extensions), userMetadata, userOverrides.extensions, globalBaseDir);
1853
1958
  // User skills from ~/.pi/agent/
1854
1959
  addResources("skills", collectAutoSkillEntries(userDirs.skills, "pi"), userMetadata, userOverrides.skills, globalBaseDir);
1960
+ // User rules from ~/.pi/agent/
1961
+ addResources("rules", collectAutoRuleEntries(userDirs.rules, "pi"), userMetadata, userOverrides.rules, globalBaseDir);
1855
1962
  // User skills from ~/.agents/ (with its own baseDir)
1856
1963
  const userAgentsBaseDir = dirname(userAgentsSkillsDir);
1857
1964
  const userAgentsMetadata = {
@@ -1859,6 +1966,13 @@ export class DefaultPackageManager {
1859
1966
  baseDir: userAgentsBaseDir,
1860
1967
  };
1861
1968
  addResources("skills", collectAutoSkillEntries(userAgentsSkillsDir, "agents"), userAgentsMetadata, userOverrides.skills, userAgentsBaseDir);
1969
+ // User rules from ~/.agents/ (with its own baseDir)
1970
+ const userAgentsRulesBaseDir = dirname(userAgentsRulesDir);
1971
+ const userAgentsRulesMetadata = {
1972
+ ...userMetadata,
1973
+ baseDir: userAgentsRulesBaseDir,
1974
+ };
1975
+ addResources("rules", collectAutoRuleEntries(userAgentsRulesDir, "agents"), userAgentsRulesMetadata, userOverrides.rules, userAgentsRulesBaseDir);
1862
1976
  addResources("prompts", collectAutoPromptEntries(userDirs.prompts), userMetadata, userOverrides.prompts, globalBaseDir);
1863
1977
  addResources("themes", collectAutoThemeEntries(userDirs.themes), userMetadata, userOverrides.themes, globalBaseDir);
1864
1978
  }
@@ -1888,6 +2002,8 @@ export class DefaultPackageManager {
1888
2002
  return accumulator.extensions;
1889
2003
  case "skills":
1890
2004
  return accumulator.skills;
2005
+ case "rules":
2006
+ return accumulator.rules;
1891
2007
  case "prompts":
1892
2008
  return accumulator.prompts;
1893
2009
  case "themes":
@@ -1907,6 +2023,7 @@ export class DefaultPackageManager {
1907
2023
  return {
1908
2024
  extensions: new Map(),
1909
2025
  skills: new Map(),
2026
+ rules: new Map(),
1910
2027
  prompts: new Map(),
1911
2028
  themes: new Map(),
1912
2029
  };
@@ -1931,6 +2048,7 @@ export class DefaultPackageManager {
1931
2048
  return {
1932
2049
  extensions: mapToResolved(accumulator.extensions),
1933
2050
  skills: mapToResolved(accumulator.skills),
2051
+ rules: mapToResolved(accumulator.rules),
1934
2052
  prompts: mapToResolved(accumulator.prompts),
1935
2053
  themes: mapToResolved(accumulator.themes),
1936
2054
  };