@nredd/pi-subagents 0.0.0-stage → 0.22.0-nredd.10

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 (88) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1444 -2
  3. package/dist/chunks/chunk-MSGGFB5Q.ts +6755 -0
  4. package/dist/chunks/chunk-MSGGFB5Q.ts.map +7 -0
  5. package/dist/chunks/conversation-viewer-A7AMRDVY.ts +15 -0
  6. package/dist/chunks/conversation-viewer-A7AMRDVY.ts.map +7 -0
  7. package/dist/index.ts +9874 -0
  8. package/dist/index.ts.map +7 -0
  9. package/package.json +82 -4
  10. package/src/abortable.ts +43 -0
  11. package/src/agent-color.ts +161 -0
  12. package/src/agent-file-toggle.ts +298 -0
  13. package/src/agent-manager.ts +2431 -0
  14. package/src/agent-runner.ts +1703 -0
  15. package/src/agent-source-badge.ts +75 -0
  16. package/src/agent-types.ts +346 -0
  17. package/src/child-context.ts +33 -0
  18. package/src/clock.ts +25 -0
  19. package/src/completion-outbox.ts +144 -0
  20. package/src/context.ts +58 -0
  21. package/src/cross-extension-rpc.ts +200 -0
  22. package/src/custom-agents.ts +441 -0
  23. package/src/default-agents.ts +126 -0
  24. package/src/detached-results.ts +150 -0
  25. package/src/enabled-models.ts +181 -0
  26. package/src/enterprise-local.ts +67 -0
  27. package/src/env.ts +33 -0
  28. package/src/error-message.ts +11 -0
  29. package/src/git-path.ts +66 -0
  30. package/src/group-join.ts +142 -0
  31. package/src/home-paths.ts +27 -0
  32. package/src/index.ts +5047 -0
  33. package/src/invocation-config.ts +158 -0
  34. package/src/memory.ts +179 -0
  35. package/src/mention-clone.ts +200 -0
  36. package/src/mention.ts +141 -0
  37. package/src/model-call.ts +83 -0
  38. package/src/model-resolver.ts +333 -0
  39. package/src/model-scope.ts +71 -0
  40. package/src/model-selection.ts +170 -0
  41. package/src/model-tiers.ts +176 -0
  42. package/src/nested-tools.ts +512 -0
  43. package/src/notification-result.ts +118 -0
  44. package/src/output-file.ts +186 -0
  45. package/src/package-resources.ts +639 -0
  46. package/src/plan-mode-children.ts +176 -0
  47. package/src/process-budget.ts +346 -0
  48. package/src/prompts.ts +161 -0
  49. package/src/quota-admission.ts +121 -0
  50. package/src/resource-loader.ts +65 -0
  51. package/src/schedule-store.ts +153 -0
  52. package/src/schedule.ts +514 -0
  53. package/src/settings.ts +851 -0
  54. package/src/skill-loader.ts +288 -0
  55. package/src/stale-ctx.ts +16 -0
  56. package/src/startup-error.ts +29 -0
  57. package/src/status-note.ts +113 -0
  58. package/src/structured-output.ts +130 -0
  59. package/src/types.ts +487 -0
  60. package/src/ui/agent-mention.ts +219 -0
  61. package/src/ui/agent-row.ts +245 -0
  62. package/src/ui/agent-widget.ts +722 -0
  63. package/src/ui/conversation-viewer.ts +837 -0
  64. package/src/ui/fallback-flag.ts +114 -0
  65. package/src/ui/fleet-list.ts +1020 -0
  66. package/src/ui/fleet-state.ts +154 -0
  67. package/src/ui/notification-view.ts +139 -0
  68. package/src/ui/schedule-menu.ts +105 -0
  69. package/src/ui/select-item.ts +45 -0
  70. package/src/ui/viewer-keys.ts +39 -0
  71. package/src/ui/workflow-card.ts +459 -0
  72. package/src/ui/workflow-dialog.ts +1138 -0
  73. package/src/ui/workflow-menu.ts +193 -0
  74. package/src/usage.ts +167 -0
  75. package/src/workflow/collisions.ts +123 -0
  76. package/src/workflow/entry.ts +47 -0
  77. package/src/workflow/host.ts +398 -0
  78. package/src/workflow/journal.ts +176 -0
  79. package/src/workflow/json-schema.ts +129 -0
  80. package/src/workflow/meta.ts +329 -0
  81. package/src/workflow/progress.ts +554 -0
  82. package/src/workflow/runtime.ts +1249 -0
  83. package/src/workflow/saved.ts +259 -0
  84. package/src/workflow/task.ts +317 -0
  85. package/src/workflow/tool-description.ts +200 -0
  86. package/src/workflow/worker-source.ts +903 -0
  87. package/src/worktree.ts +520 -0
  88. package/src/xml.ts +13 -0
@@ -0,0 +1,114 @@
1
+ /**
2
+ * fallback-flag.ts -- the ONE compact indicator for "this agent ran on another
3
+ * model than configured", shared by every renderer that shows model info.
4
+ *
5
+ * Rows are `label + stats` clamped from the right, so anything appended after
6
+ * unbounded text (a description, an error, a canonical model id) is the first
7
+ * thing a narrow terminal cuts. The flag is therefore always rendered FIRST and
8
+ * the rest is truncated around it. Renderers must use these helpers rather than
9
+ * building their own marker; `test/fallback-flag-renderers.test.ts` walks every
10
+ * renderer and fails the ones that do not.
11
+ */
12
+ import { stripTerminalSequences, truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@earendil-works/pi-tui";
13
+ import type { TierDisclosure } from "../model-tiers.js";
14
+
15
+ /** Minimal theme surface, so this module has no dependency on the widgets that use it. */
16
+ interface FlagTheme {
17
+ fg(color: string, text: string): string;
18
+ }
19
+
20
+ /** Anything that can carry the fallback: a record, details or notice details. */
21
+ export interface FallbackCarrier {
22
+ modelFallback?: unknown;
23
+ modelNote?: string;
24
+ modelTier?: TierDisclosure;
25
+ }
26
+
27
+ /** Whether this tier's answer differs from the member/profile admitted for it. */
28
+ function switchedWithinTier(tier: TierDisclosure): boolean {
29
+ if (tier.kind !== "routed" && tier.kind !== "static") return false;
30
+ const baseline = tier.kind === "routed" ? tier.admitted : tier.member;
31
+ return baseline !== undefined && tier.answered !== undefined && tier.answered !== baseline;
32
+ }
33
+
34
+ /** Whether `carrier` needs an actionable fallback warning, not merely tier identity. */
35
+ export const hasFallback = (carrier: FallbackCarrier | undefined): boolean => {
36
+ if (carrier?.modelFallback !== undefined) return true;
37
+ const tier = carrier?.modelTier;
38
+ if (!tier) return carrier?.modelNote !== undefined;
39
+ return tier.kind === "unmapped" || tier.kind === "unavailable" || switchedWithinTier(tier);
40
+ };
41
+
42
+ /** Plain tier identity/outcome flag, or `[fallback]`; group counts retain the same identity. */
43
+ export function fallbackFlagText(count = 1, carrier?: FallbackCarrier): string {
44
+ const tier = carrier?.modelTier;
45
+ const suffix = count > 1 ? ` x${count}` : "";
46
+ return tier ? `[@${tier.tier}${tier.kind !== "routed" && tier.kind !== "static" ? ` ${tier.kind}` : ""}${suffix}]`
47
+ : `[fallback${suffix}]`;
48
+ }
49
+
50
+ /** The themed tier identity or actionable fallback flag for `carrier`. */
51
+ export function fallbackFlag(theme: FlagTheme, carrier: FallbackCarrier | undefined, count = 1): string {
52
+ if (carrier?.modelTier) return theme.fg(hasFallback(carrier) ? "warning" : "dim", fallbackFlagText(count, carrier));
53
+ return hasFallback(carrier) ? theme.fg("warning", fallbackFlagText(count, carrier)) : "";
54
+ }
55
+
56
+ /** What a flag degrades to when even it does not fit; plain so it cannot depend on a theme. */
57
+ const MINIMAL_FLAGS = ["[fb]", "!"] as const;
58
+
59
+ /**
60
+ * Wrap control text into a fixed row budget while preserving both its opening
61
+ * and final diagnosis around an explicit omitted-rows marker. The budget is at
62
+ * least three rows: one each for the opening, the marker and the diagnosis.
63
+ * A non-finite `maxRows` gets that floor rather than poisoning the slices.
64
+ */
65
+ export function boundedWrappedRows(text: string, width: number, maxRows: number, marker: string): string[] {
66
+ const rows = wrapTextWithAnsi(text, width);
67
+ const budget = Number.isFinite(maxRows) ? Math.max(3, Math.trunc(maxRows)) : 3;
68
+ if (rows.length <= budget) return rows;
69
+
70
+ // Reserve a row for the omission marker and favor the final rows: fallback
71
+ // diagnoses live at the end, while the first row still names the control text.
72
+ // At least two rows are omitted, so the marker never replaces a single row.
73
+ const firstCount = Math.max(1, Math.floor((budget - 1) / 2));
74
+ const lastCount = budget - firstCount - 1;
75
+ const omitted = rows.length - firstCount - lastCount;
76
+ const omission = stripTerminalSequences(
77
+ truncateToWidth(`${marker} ${omitted} more lines`, width, ""),
78
+ );
79
+ return [...rows.slice(0, firstCount), omission, ...rows.slice(-lastCount)];
80
+ }
81
+
82
+ /**
83
+ * `prefix + flag + rest`, never wider than `width`, and the flag is never cut.
84
+ *
85
+ * Normal case: the prefix and the flag are reserved first and `rest` (a string,
86
+ * or a function of the width left for it) is truncated to what remains.
87
+ *
88
+ * Narrow case, when `prefix + flag + " "` exceeds `width`: the prefix and then
89
+ * the rest are dropped before the flag is. If the flag alone still does not
90
+ * fit, it degrades to a plain `[fb]`, then `!`. Only a zero width renders
91
+ * nothing. An empty string `rest` renders no separator after the flag, so a
92
+ * caller sizing the flag alone gets just the flag.
93
+ */
94
+ export function withLeadingFlag(
95
+ prefix: string,
96
+ flag: string,
97
+ rest: string | ((inner: number) => string),
98
+ width: number,
99
+ ): string {
100
+ const lead = flag ? `${prefix}${flag}${rest === "" ? "" : " "}` : prefix;
101
+ if (!flag || visibleWidth(lead) <= width) {
102
+ const inner = Math.max(0, width - visibleWidth(lead));
103
+ const body = typeof rest === "function" ? rest(inner) : truncateToWidth(rest, inner);
104
+ return truncateToWidth(lead + body, width);
105
+ }
106
+ const flagWidth = visibleWidth(flag);
107
+ if (flagWidth <= width) {
108
+ const inner = width - flagWidth - 1;
109
+ if (inner < 1 || rest === "") return flag;
110
+ const body = typeof rest === "function" ? rest(inner) : truncateToWidth(rest, inner);
111
+ return truncateToWidth(`${flag} ${body}`, width);
112
+ }
113
+ return MINIMAL_FLAGS.find(m => visibleWidth(m) <= width) ?? "";
114
+ }