@fleetagent/pi-coding-agent 0.0.9 → 0.0.11

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 (136) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +9 -0
  3. package/dist/cli/args.d.ts +3 -0
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +18 -0
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/core/agent-session.d.ts +13 -3
  8. package/dist/core/agent-session.d.ts.map +1 -1
  9. package/dist/core/agent-session.js +42 -8
  10. package/dist/core/agent-session.js.map +1 -1
  11. package/dist/core/bash-executor.d.ts +5 -3
  12. package/dist/core/bash-executor.d.ts.map +1 -1
  13. package/dist/core/bash-executor.js +4 -2
  14. package/dist/core/bash-executor.js.map +1 -1
  15. package/dist/core/extensions/index.d.ts +1 -1
  16. package/dist/core/extensions/index.d.ts.map +1 -1
  17. package/dist/core/extensions/index.js.map +1 -1
  18. package/dist/core/extensions/loader.d.ts.map +1 -1
  19. package/dist/core/extensions/loader.js +86 -0
  20. package/dist/core/extensions/loader.js.map +1 -1
  21. package/dist/core/extensions/runner.d.ts +3 -0
  22. package/dist/core/extensions/runner.d.ts.map +1 -1
  23. package/dist/core/extensions/runner.js +27 -0
  24. package/dist/core/extensions/runner.js.map +1 -1
  25. package/dist/core/extensions/types.d.ts +56 -3
  26. package/dist/core/extensions/types.d.ts.map +1 -1
  27. package/dist/core/extensions/types.js.map +1 -1
  28. package/dist/core/pi-agent.d.ts +2 -0
  29. package/dist/core/pi-agent.d.ts.map +1 -1
  30. package/dist/core/pi-agent.js +3 -0
  31. package/dist/core/pi-agent.js.map +1 -1
  32. package/dist/core/prompt-templates.d.ts +5 -0
  33. package/dist/core/prompt-templates.d.ts.map +1 -1
  34. package/dist/core/prompt-templates.js +115 -0
  35. package/dist/core/prompt-templates.js.map +1 -1
  36. package/dist/core/resource-loader.d.ts +15 -0
  37. package/dist/core/resource-loader.d.ts.map +1 -1
  38. package/dist/core/resource-loader.js +332 -40
  39. package/dist/core/resource-loader.js.map +1 -1
  40. package/dist/core/rules.d.ts +6 -0
  41. package/dist/core/rules.d.ts.map +1 -1
  42. package/dist/core/rules.js +216 -0
  43. package/dist/core/rules.js.map +1 -1
  44. package/dist/core/skills.d.ts +6 -0
  45. package/dist/core/skills.d.ts.map +1 -1
  46. package/dist/core/skills.js +216 -0
  47. package/dist/core/skills.js.map +1 -1
  48. package/dist/core/slash-commands.d.ts.map +1 -1
  49. package/dist/core/slash-commands.js +1 -0
  50. package/dist/core/slash-commands.js.map +1 -1
  51. package/dist/core/source-info.d.ts +2 -0
  52. package/dist/core/source-info.d.ts.map +1 -1
  53. package/dist/core/source-info.js +6 -0
  54. package/dist/core/source-info.js.map +1 -1
  55. package/dist/core/tools/bash.d.ts +6 -29
  56. package/dist/core/tools/bash.d.ts.map +1 -1
  57. package/dist/core/tools/bash.js +27 -101
  58. package/dist/core/tools/bash.js.map +1 -1
  59. package/dist/core/tools/edit-diff.d.ts +3 -2
  60. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  61. package/dist/core/tools/edit-diff.js +6 -8
  62. package/dist/core/tools/edit-diff.js.map +1 -1
  63. package/dist/core/tools/edit.d.ts +3 -16
  64. package/dist/core/tools/edit.d.ts.map +1 -1
  65. package/dist/core/tools/edit.js +12 -18
  66. package/dist/core/tools/edit.js.map +1 -1
  67. package/dist/core/tools/find.d.ts +3 -17
  68. package/dist/core/tools/find.d.ts.map +1 -1
  69. package/dist/core/tools/find.js +13 -25
  70. package/dist/core/tools/find.js.map +1 -1
  71. package/dist/core/tools/grep.d.ts +3 -14
  72. package/dist/core/tools/grep.d.ts.map +1 -1
  73. package/dist/core/tools/grep.js +95 -43
  74. package/dist/core/tools/grep.js.map +1 -1
  75. package/dist/core/tools/index.d.ts +17 -15
  76. package/dist/core/tools/index.d.ts.map +1 -1
  77. package/dist/core/tools/index.js +53 -52
  78. package/dist/core/tools/index.js.map +1 -1
  79. package/dist/core/tools/ls.d.ts +3 -20
  80. package/dist/core/tools/ls.d.ts.map +1 -1
  81. package/dist/core/tools/ls.js +11 -22
  82. package/dist/core/tools/ls.js.map +1 -1
  83. package/dist/core/tools/operations.d.ts +145 -0
  84. package/dist/core/tools/operations.d.ts.map +1 -0
  85. package/dist/core/tools/operations.js +418 -0
  86. package/dist/core/tools/operations.js.map +1 -0
  87. package/dist/core/tools/read.d.ts +3 -16
  88. package/dist/core/tools/read.d.ts.map +1 -1
  89. package/dist/core/tools/read.js +9 -15
  90. package/dist/core/tools/read.js.map +1 -1
  91. package/dist/core/tools/render-utils.d.ts +9 -0
  92. package/dist/core/tools/render-utils.d.ts.map +1 -1
  93. package/dist/core/tools/render-utils.js +14 -0
  94. package/dist/core/tools/render-utils.js.map +1 -1
  95. package/dist/core/tools/write.d.ts +3 -14
  96. package/dist/core/tools/write.d.ts.map +1 -1
  97. package/dist/core/tools/write.js +9 -12
  98. package/dist/core/tools/write.js.map +1 -1
  99. package/dist/index.d.ts +2 -2
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +1 -1
  102. package/dist/index.js.map +1 -1
  103. package/dist/main.d.ts.map +1 -1
  104. package/dist/main.js +40 -5
  105. package/dist/main.js.map +1 -1
  106. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  107. package/dist/modes/interactive/components/tool-execution.js +2 -2
  108. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  109. package/dist/modes/interactive/interactive-mode.d.ts +3 -0
  110. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  111. package/dist/modes/interactive/interactive-mode.js +73 -9
  112. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  113. package/dist/modes/rpc/rpc-client.d.ts +9 -0
  114. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  115. package/dist/modes/rpc/rpc-client.js +14 -0
  116. package/dist/modes/rpc/rpc-client.js.map +1 -1
  117. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  118. package/dist/modes/rpc/rpc-mode.js +9 -0
  119. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  120. package/dist/modes/rpc/rpc-types.d.ts +22 -0
  121. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  122. package/dist/modes/rpc/rpc-types.js.map +1 -1
  123. package/docs/extensions.md +83 -5
  124. package/docs/usage.md +2 -0
  125. package/examples/extensions/README.md +0 -1
  126. package/examples/extensions/bash-spawn-hook.ts +2 -2
  127. package/examples/extensions/built-in-tool-renderer.ts +12 -5
  128. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  129. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  130. package/examples/extensions/minimal-mode.ts +9 -7
  131. package/examples/extensions/sandbox/index.ts +55 -56
  132. package/examples/extensions/sandbox/package.json +1 -1
  133. package/examples/extensions/with-deps/package.json +1 -1
  134. package/npm-shrinkwrap.json +12 -12
  135. package/package.json +4 -4
  136. package/examples/extensions/ssh.ts +0 -220
@@ -11,6 +11,7 @@ import { CombinedAutocompleteProvider, Container, fuzzyFilter, getCapabilities,
11
11
  import { spawn, spawnSync } from "child_process";
12
12
  import { APP_NAME, APP_TITLE, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, getShareViewerUrl, PACKAGE_NAME, VERSION, } from "../../config.js";
13
13
  import { parseSkillBlock } from "../../core/agent-session.js";
14
+ import { executeBashWithOperations } from "../../core/bash-executor.js";
14
15
  import { FooterDataProvider } from "../../core/footer-data-provider.js";
15
16
  import { KeybindingsManager } from "../../core/keybindings.js";
16
17
  import { createCompactionSummaryMessage } from "../../core/messages.js";
@@ -21,6 +22,7 @@ import { BUILT_IN_PROVIDER_DISPLAY_NAMES } from "../../core/provider-display-nam
21
22
  import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../core/session-cwd.js";
22
23
  import { LocalSessionManager } from "../../core/session-manager.js";
23
24
  import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
25
+ import { getSourceBackendIcon } from "../../core/source-info.js";
24
26
  import { isInstallTelemetryEnabled } from "../../core/telemetry.js";
25
27
  import { getChangelogPath, getNewEntries, parseChangelog } from "../../utils/changelog.js";
26
28
  import { copyToClipboard } from "../../utils/clipboard.js";
@@ -265,7 +267,8 @@ export class InteractiveMode {
265
267
  if (!sourceTag) {
266
268
  return description;
267
269
  }
268
- return description ? `[${sourceTag}] ${description}` : `[${sourceTag}]`;
270
+ const backendIcon = getSourceBackendIcon(sourceInfo);
271
+ return description ? `[${backendIcon} ${sourceTag}] ${description}` : `[${backendIcon} ${sourceTag}]`;
269
272
  }
270
273
  getBuiltInCommandConflictDiagnostics(extensionRunner) {
271
274
  const builtinNames = new Set(BUILTIN_SLASH_COMMANDS.map((command) => command.name));
@@ -914,7 +917,8 @@ export class InteractiveMode {
914
917
  if (sourceInfo) {
915
918
  const shortPath = this.getShortPath(p, sourceInfo);
916
919
  const { label, scopeLabel } = this.getDisplaySourceInfo(sourceInfo);
917
- const labelText = scopeLabel ? `${label} (${scopeLabel})` : label;
920
+ const backendIcon = getSourceBackendIcon(sourceInfo);
921
+ const labelText = scopeLabel ? `${backendIcon} ${label} (${scopeLabel})` : `${backendIcon} ${label}`;
918
922
  return `${labelText} ${shortPath}`;
919
923
  }
920
924
  return this.formatDisplayPath(p);
@@ -1017,8 +1021,10 @@ export class InteractiveMode {
1017
1021
  const contextFiles = this.session.resourceLoader.getAgentsFiles().agentsFiles;
1018
1022
  if (contextFiles.length > 0) {
1019
1023
  this.chatContainer.addChild(new Spacer(1));
1024
+ const contextBackendInfo = this.session.getToolBackendInfo?.();
1025
+ const contextBackendIcon = contextBackendInfo?.type === "ssh" ? "☁" : "🖥";
1020
1026
  const contextList = contextFiles
1021
- .map((f) => theme.fg("dim", ` ${this.formatDisplayPath(f.path)}`))
1027
+ .map((f) => theme.fg("dim", ` ${f.path.startsWith(getAgentDir()) ? "🖥" : contextBackendIcon} ${this.formatDisplayPath(f.path)}`))
1022
1028
  .join("\n");
1023
1029
  const contextCompactList = formatCompactList(contextFiles.map((contextFile) => this.formatContextPath(contextFile.path)), { sort: false });
1024
1030
  addLoadedSection("Context", contextCompactList, contextList);
@@ -1027,8 +1033,8 @@ export class InteractiveMode {
1027
1033
  if (skills.length > 0) {
1028
1034
  const groups = this.buildScopeGroups(skills.map((skill) => ({ path: skill.filePath, sourceInfo: skill.sourceInfo })));
1029
1035
  const skillList = this.formatScopeGroups(groups, {
1030
- formatPath: (item) => this.formatDisplayPath(item.path),
1031
- formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
1036
+ formatPath: (item) => `${getSourceBackendIcon(item.sourceInfo)} ${this.formatDisplayPath(item.path)}`,
1037
+ formatPackagePath: (item) => `${getSourceBackendIcon(item.sourceInfo)} ${this.getShortPath(item.path, item.sourceInfo)}`,
1032
1038
  });
1033
1039
  const skillCompactList = formatCompactList(skills.map((skill) => skill.name));
1034
1040
  addLoadedSection("Skills", skillCompactList, skillList);
@@ -1037,8 +1043,8 @@ export class InteractiveMode {
1037
1043
  if (rules.length > 0) {
1038
1044
  const groups = this.buildScopeGroups(rules.map((rule) => ({ path: rule.filePath, sourceInfo: rule.sourceInfo })));
1039
1045
  const ruleList = this.formatScopeGroups(groups, {
1040
- formatPath: (item) => this.formatDisplayPath(item.path),
1041
- formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
1046
+ formatPath: (item) => `${getSourceBackendIcon(item.sourceInfo)} ${this.formatDisplayPath(item.path)}`,
1047
+ formatPackagePath: (item) => `${getSourceBackendIcon(item.sourceInfo)} ${this.getShortPath(item.path, item.sourceInfo)}`,
1042
1048
  });
1043
1049
  const ruleCompactList = formatCompactList(rules.map((rule) => rule.name));
1044
1050
  addLoadedSection("Rules", ruleCompactList, ruleList);
@@ -1050,11 +1056,11 @@ export class InteractiveMode {
1050
1056
  const templateList = this.formatScopeGroups(groups, {
1051
1057
  formatPath: (item) => {
1052
1058
  const template = templateByPath.get(item.path);
1053
- return template ? `/${template.name}` : this.formatDisplayPath(item.path);
1059
+ return `${getSourceBackendIcon(item.sourceInfo)} ${template ? `/${template.name}` : this.formatDisplayPath(item.path)}`;
1054
1060
  },
1055
1061
  formatPackagePath: (item) => {
1056
1062
  const template = templateByPath.get(item.path);
1057
- return template ? `/${template.name}` : this.formatDisplayPath(item.path);
1063
+ return `${getSourceBackendIcon(item.sourceInfo)} ${template ? `/${template.name}` : this.formatDisplayPath(item.path)}`;
1058
1064
  },
1059
1065
  });
1060
1066
  const promptCompactList = formatCompactList(templates.map((template) => `/${template.name}`));
@@ -1211,6 +1217,7 @@ export class InteractiveMode {
1211
1217
  });
1212
1218
  setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
1213
1219
  this.setupAutocompleteProvider();
1220
+ this.updateToolBackendStatus();
1214
1221
  const extensionRunner = this.session.extensionRunner;
1215
1222
  this.setupExtensionShortcuts(extensionRunner);
1216
1223
  this.showLoadedResources({ force: false, showDiagnosticsWhenQuiet: true });
@@ -1276,6 +1283,12 @@ export class InteractiveMode {
1276
1283
  ui: this.createExtensionUIContext(),
1277
1284
  hasUI: true,
1278
1285
  cwd: this.activeSession.getCwd(),
1286
+ toolOperations: this.session.getToolOperations(),
1287
+ getToolBackendInfo: () => this.session.getToolBackendInfo(),
1288
+ execToolBackend: (command, options) => {
1289
+ const operations = this.session.getToolOperations();
1290
+ return executeBashWithOperations(command, options?.cwd ?? operations.cwd, operations, options);
1291
+ },
1279
1292
  session: this.activeSession,
1280
1293
  modelRegistry: this.session.modelRegistry,
1281
1294
  model: this.session.model,
@@ -1325,6 +1338,18 @@ export class InteractiveMode {
1325
1338
  this.footerDataProvider.setExtensionStatus(key, text);
1326
1339
  this.ui.requestRender();
1327
1340
  }
1341
+ formatToolBackendStatus(info) {
1342
+ if (info.type === "local") {
1343
+ return theme.fg("dim", `tools: local ${info.cwd}`);
1344
+ }
1345
+ if (info.configured) {
1346
+ return theme.fg("accent", `tools: ssh ${info.remote}:${info.cwd}`);
1347
+ }
1348
+ return theme.fg("warning", `tools: ssh not configured ${info.cwd}`);
1349
+ }
1350
+ updateToolBackendStatus() {
1351
+ this.setExtensionStatus("toolBackend", this.formatToolBackendStatus(this.session.getToolBackendInfo()));
1352
+ }
1328
1353
  getWorkingLoaderMessage() {
1329
1354
  return this.workingMessage ?? this.defaultWorkingMessage;
1330
1355
  }
@@ -2038,6 +2063,11 @@ export class InteractiveMode {
2038
2063
  this.editor.setText("");
2039
2064
  return;
2040
2065
  }
2066
+ if (text === "/ssh-sandbox" || text.startsWith("/ssh-sandbox ")) {
2067
+ this.editor.setText("");
2068
+ await this.handleSshSandboxCommand(text);
2069
+ return;
2070
+ }
2041
2071
  if (text === "/changelog") {
2042
2072
  this.handleChangelogCommand();
2043
2073
  this.editor.setText("");
@@ -4365,6 +4395,40 @@ export class InteractiveMode {
4365
4395
  this.chatContainer.addChild(new Text(theme.fg("dim", `Session name set: ${name}`), 1, 0));
4366
4396
  this.ui.requestRender();
4367
4397
  }
4398
+ async handleSshSandboxCommand(text) {
4399
+ const args = text.replace(/^\/ssh-sandbox\s*/, "").trim();
4400
+ if (!args || args === "status") {
4401
+ this.showStatus(this.formatToolBackendStatus(this.session.getToolBackendInfo()));
4402
+ return;
4403
+ }
4404
+ if (args === "clear") {
4405
+ try {
4406
+ this.session.clearSshSandbox();
4407
+ this.updateToolBackendStatus();
4408
+ this.showStatus("SSH sandbox cleared");
4409
+ }
4410
+ catch (error) {
4411
+ this.showError(error instanceof Error ? error.message : String(error));
4412
+ }
4413
+ return;
4414
+ }
4415
+ const [targetArg, cwdArg] = args.split(/\s+/, 2);
4416
+ if (!targetArg) {
4417
+ this.showWarning("Usage: /ssh-sandbox <user@host[:/path]> [path]");
4418
+ return;
4419
+ }
4420
+ const separatorIndex = targetArg.indexOf(":");
4421
+ const remote = separatorIndex === -1 ? targetArg : targetArg.slice(0, separatorIndex);
4422
+ const cwd = cwdArg ?? (separatorIndex === -1 ? undefined : targetArg.slice(separatorIndex + 1));
4423
+ try {
4424
+ const info = await this.session.configureSshSandbox({ remote, cwd });
4425
+ this.updateToolBackendStatus();
4426
+ this.showStatus(this.formatToolBackendStatus(info));
4427
+ }
4428
+ catch (error) {
4429
+ this.showError(`Failed to configure SSH sandbox: ${error instanceof Error ? error.message : String(error)}`);
4430
+ }
4431
+ }
4368
4432
  handleSessionCommand() {
4369
4433
  const stats = this.session.getSessionStats();
4370
4434
  const sessionName = this.activeSession.getSessionName();