pi-landstrip 0.17.18 → 0.17.19

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 (2) hide show
  1. package/package.json +2 -2
  2. package/subagents.ts +35 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-landstrip",
3
- "version": "0.17.18",
3
+ "version": "0.17.19",
4
4
  "description": "Sandbox-aware Pi subagents and interactive command permissions",
5
5
  "keywords": [
6
6
  "landstrip",
@@ -38,7 +38,7 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@earendil-works/pi-tui": "^0.80.6",
41
- "@landstrip/landstrip": "^0.17.18",
41
+ "@landstrip/landstrip": "^0.17.19",
42
42
  "minimatch": "^10.2.5"
43
43
  },
44
44
  "devDependencies": {
package/subagents.ts CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  type Theme,
27
27
  type ToolDefinition,
28
28
  } from '@earendil-works/pi-coding-agent';
29
- import { matchesKey, Text, truncateToWidth } from '@earendil-works/pi-tui';
29
+ import { matchesKey, Text, truncateToWidth, visibleWidth } from '@earendil-works/pi-tui';
30
30
  import { Type } from 'typebox';
31
31
 
32
32
  import {
@@ -52,6 +52,28 @@ const MAX_DEPTH = 3;
52
52
  const packageDir = dirname(fileURLToPath(import.meta.url));
53
53
  const MAX_TASK_OUTPUT_BYTES = 64 * 1024;
54
54
  const INSPECTOR_BODY_LINES = 16;
55
+
56
+ function boxTop(theme: Theme, width: number, title: string): string {
57
+ if (width < 5) return truncateToWidth(theme.fg('accent', title), Math.max(1, width));
58
+ const label = theme.fg('accent', ` ${title} `);
59
+ const fill = theme.fg('border', '─'.repeat(Math.max(0, width - 4 - visibleWidth(label))));
60
+ return `${theme.fg('border', '╭─')}${label}${fill}${theme.fg('border', '─╮')}`;
61
+ }
62
+
63
+ function boxRow(theme: Theme, width: number, content = ''): string {
64
+ if (width < 5) return truncateToWidth(content, Math.max(1, width));
65
+ const innerWidth = Math.max(1, width - 4);
66
+ const border = theme.fg('border', '│');
67
+ const line = truncateToWidth(content, innerWidth);
68
+ return `${border} ${line}${' '.repeat(Math.max(0, innerWidth - visibleWidth(line)))} ${border}`;
69
+ }
70
+
71
+ function boxBottom(theme: Theme, width: number): string {
72
+ if (width < 5) return '';
73
+ const border = (value: string) => theme.fg('border', value);
74
+ return `${border('╰')}${border('─'.repeat(Math.max(0, width - 2)))}${border('╯')}`;
75
+ }
76
+
55
77
  interface PiPackage {
56
78
  readonly cliEntry: string;
57
79
  readonly version: readonly [number, number, number];
@@ -895,11 +917,16 @@ export class SubagentRuntime {
895
917
  await ctx.ui.custom<void>(
896
918
  (tui, theme, _keybindings, done) => ({
897
919
  render: (width: number) => {
898
- const fit = (line: string) => truncateToWidth(line, Math.max(1, width));
920
+ const contentWidth = Math.max(1, width - 4);
921
+ const box = (title: string, lines: string[]) => [
922
+ boxTop(theme, width, title),
923
+ ...lines.map((line) => boxRow(theme, width, line)),
924
+ boxBottom(theme, width),
925
+ ];
899
926
  if (!detail) {
900
927
  const start = Math.max(0, Math.min(selected - 6, tasks.length - 12));
901
928
  const shown = tasks.slice(start, start + 12);
902
- const lines = [theme.fg('accent', theme.bold('Subagent sessions'))];
929
+ const lines: string[] = [];
903
930
  for (const [offset, task] of shown.entries()) {
904
931
  const index = start + offset;
905
932
  const cursor = index === selected ? theme.fg('accent', '›') : ' ';
@@ -909,7 +936,7 @@ export class SubagentRuntime {
909
936
  );
910
937
  }
911
938
  lines.push('', theme.fg('dim', '↑↓ select enter inspect esc close'));
912
- return lines.map(fit);
939
+ return box('Subagent Sessions', lines);
913
940
  }
914
941
 
915
942
  const task = tasks[selected];
@@ -946,7 +973,10 @@ export class SubagentRuntime {
946
973
  lines.push(
947
974
  theme.fg('dim', 'Parent p/backspace Prev ← Next → ↑↓ scroll r refresh esc back'),
948
975
  );
949
- return lines.map(fit);
976
+ return box(
977
+ 'Subagent Session',
978
+ lines.map((line) => truncateToWidth(line, contentWidth)),
979
+ );
950
980
  },
951
981
  handleInput: (data: string) => {
952
982
  if (!detail) {