pi-soly 1.9.3 → 1.11.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 (104) hide show
  1. package/ask/index.ts +12 -11
  2. package/ask/picker.ts +356 -76
  3. package/ask/prompt.ts +6 -2
  4. package/ask/tests/picker.test.ts +273 -82
  5. package/codemap.ts +276 -0
  6. package/hotreload.ts +239 -0
  7. package/init.ts +302 -0
  8. package/mcp/CHANGELOG.md +384 -0
  9. package/mcp/LICENSE +21 -0
  10. package/mcp/OAUTH.md +355 -0
  11. package/mcp/README.md +410 -0
  12. package/mcp/__tests__/agent-dir-paths.upstream-test.ts +80 -0
  13. package/mcp/__tests__/cli.upstream-test.ts +97 -0
  14. package/mcp/__tests__/commands-onboarding.upstream-test.ts +157 -0
  15. package/mcp/__tests__/config.upstream-test.ts +303 -0
  16. package/mcp/__tests__/consent-manager.upstream-test.ts +151 -0
  17. package/mcp/__tests__/direct-tools-auto-auth.upstream-test.ts +218 -0
  18. package/mcp/__tests__/direct-tools.upstream-test.ts +299 -0
  19. package/mcp/__tests__/elicitation-handler.upstream-test.ts +346 -0
  20. package/mcp/__tests__/elicitation-sdk-integration.upstream-test.ts +140 -0
  21. package/mcp/__tests__/errors.upstream-test.ts +218 -0
  22. package/mcp/__tests__/fixtures/elicitation-server.mjs +98 -0
  23. package/mcp/__tests__/host-html-template.upstream-test.ts +278 -0
  24. package/mcp/__tests__/index-lifecycle.upstream-test.ts +484 -0
  25. package/mcp/__tests__/init-elicitation.upstream-test.ts +86 -0
  26. package/mcp/__tests__/interactive-visualizer-server.upstream-test.ts +28 -0
  27. package/mcp/__tests__/logger.upstream-test.ts +175 -0
  28. package/mcp/__tests__/mcp-auth-flow-client-credentials.upstream-test.ts +612 -0
  29. package/mcp/__tests__/mcp-auth-storage.upstream-test.ts +47 -0
  30. package/mcp/__tests__/mcp-callback-server-unref.upstream-test.ts +264 -0
  31. package/mcp/__tests__/mcp-oauth-provider.upstream-test.ts +216 -0
  32. package/mcp/__tests__/mcp-panel-auth.upstream-test.ts +206 -0
  33. package/mcp/__tests__/mcp-panel-exclude-tools.upstream-test.ts +69 -0
  34. package/mcp/__tests__/mcp-panel-keybindings.upstream-test.ts +186 -0
  35. package/mcp/__tests__/npx-resolver.upstream-test.ts +54 -0
  36. package/mcp/__tests__/oauth-handler.upstream-test.ts +77 -0
  37. package/mcp/__tests__/onboarding-state.upstream-test.ts +52 -0
  38. package/mcp/__tests__/package-manifest.upstream-test.ts +22 -0
  39. package/mcp/__tests__/proxy-modes-auto-auth.upstream-test.ts +253 -0
  40. package/mcp/__tests__/proxy-modes-discovery.upstream-test.ts +84 -0
  41. package/mcp/__tests__/proxy-modes-manual-auth.upstream-test.ts +91 -0
  42. package/mcp/__tests__/proxy-modes-ui-messages.upstream-test.ts +72 -0
  43. package/mcp/__tests__/sampling-handler.upstream-test.ts +285 -0
  44. package/mcp/__tests__/server-manager-http-auth.upstream-test.ts +144 -0
  45. package/mcp/__tests__/server-manager-sampling.upstream-test.ts +236 -0
  46. package/mcp/__tests__/tool-metadata.upstream-test.ts +111 -0
  47. package/mcp/__tests__/tool-result-renderer.upstream-test.ts +147 -0
  48. package/mcp/__tests__/ui-integration.upstream-test.ts +551 -0
  49. package/mcp/__tests__/ui-resource-handler.upstream-test.ts +303 -0
  50. package/mcp/__tests__/ui-server.upstream-test.ts +967 -0
  51. package/mcp/__tests__/ui-session-messages.upstream-test.ts +72 -0
  52. package/mcp/__tests__/ui-streaming.upstream-test.ts +543 -0
  53. package/mcp/agent-dir.ts +20 -0
  54. package/mcp/app-bridge.bundle.js +67 -0
  55. package/mcp/cli.js +184 -0
  56. package/mcp/commands.ts +422 -0
  57. package/mcp/config.ts +666 -0
  58. package/mcp/consent-manager.ts +64 -0
  59. package/mcp/direct-tools.ts +439 -0
  60. package/mcp/elicitation-handler.ts +347 -0
  61. package/mcp/errors.ts +219 -0
  62. package/mcp/glimpse-ui.ts +80 -0
  63. package/mcp/host-html-template.ts +427 -0
  64. package/mcp/index.ts +362 -0
  65. package/mcp/init.ts +362 -0
  66. package/mcp/lifecycle.ts +93 -0
  67. package/mcp/logger.ts +169 -0
  68. package/mcp/mcp-auth-flow.ts +559 -0
  69. package/mcp/mcp-auth-flow.upstream-test.ts +259 -0
  70. package/mcp/mcp-auth.ts +302 -0
  71. package/mcp/mcp-auth.upstream-test.ts +373 -0
  72. package/mcp/mcp-callback-server.ts +372 -0
  73. package/mcp/mcp-callback-server.upstream-test.ts +416 -0
  74. package/mcp/mcp-oauth-provider.ts +369 -0
  75. package/mcp/mcp-oauth-provider.upstream-test.ts +518 -0
  76. package/mcp/mcp-panel.ts +829 -0
  77. package/mcp/mcp-setup-panel.ts +580 -0
  78. package/mcp/metadata-cache.ts +201 -0
  79. package/mcp/notify.ts +111 -0
  80. package/mcp/npx-resolver.ts +424 -0
  81. package/mcp/oauth-handler.ts +57 -0
  82. package/mcp/onboarding-state.ts +68 -0
  83. package/mcp/package.json +106 -0
  84. package/mcp/panel-keys.ts +37 -0
  85. package/mcp/proxy-modes.ts +949 -0
  86. package/mcp/resource-tools.ts +17 -0
  87. package/mcp/sampling-handler.ts +268 -0
  88. package/mcp/server-manager.ts +545 -0
  89. package/mcp/state.ts +41 -0
  90. package/mcp/tool-metadata.ts +216 -0
  91. package/mcp/tool-registrar.ts +46 -0
  92. package/mcp/tool-result-renderer.ts +161 -0
  93. package/mcp/types.ts +448 -0
  94. package/mcp/ui-resource-handler.ts +146 -0
  95. package/mcp/ui-server.ts +623 -0
  96. package/mcp/ui-session.ts +386 -0
  97. package/mcp/ui-stream-types.ts +89 -0
  98. package/mcp/utils.ts +129 -0
  99. package/mcp/vitest.config.ts +14 -0
  100. package/migrate.ts +258 -0
  101. package/notification.ts +218 -0
  102. package/notifications-log.ts +83 -0
  103. package/package.json +20 -3
  104. package/status.ts +140 -0
package/status.ts ADDED
@@ -0,0 +1,140 @@
1
+ // =============================================================================
2
+ // status.ts — Comprehensive one-screen status report
3
+ // =============================================================================
4
+ //
5
+ // Used by `/soly-status`. Gathers everything in
6
+ // one place: version, version, project state, recent decisions,
7
+ // recent notifications, and (if available) token budget.
8
+ //
9
+ // Output is a multi-line string formatted for the TUI notify.
10
+ // =============================================================================
11
+
12
+ import { readFileSync } from "node:fs";
13
+ import * as path from "node:path";
14
+ import { SOLY_DIRNAME } from "./core.js";
15
+ import { readNotifications } from "./notifications-log.js";
16
+
17
+ /** Subset of project state we need (avoids pulling in whole SolyState). */
18
+ export interface StatusState {
19
+ exists: boolean;
20
+ solyDir: string;
21
+ milestone?: string;
22
+ currentPosition?: string;
23
+ phases: Array<{ number: number; name: string; slug: string; status: string }>;
24
+ features?: string[];
25
+ }
26
+
27
+ export interface StatusOptions {
28
+ /** Show this many recent decisions (from STATE.md). Default 5. */
29
+ recentDecisions?: number;
30
+ /** Show this many recent notifications. Default 5. */
31
+ recentNotifications?: number;
32
+ /** Include token budget (if available). Default true. */
33
+ includeTokenBudget?: boolean;
34
+ /** Current package version (read from package.json at build time, or passed). */
35
+ version?: string;
36
+ }
37
+
38
+ /** Format the comprehensive status report. */
39
+ export function formatStatus(
40
+ cwd: string,
41
+ state: StatusState,
42
+ options: StatusOptions = {},
43
+ ): string {
44
+ const recentDecisions = options.recentDecisions ?? 5;
45
+ const recentNotifs = options.recentNotifications ?? 5;
46
+ const version = options.version ?? "0.0.0";
47
+ const lines: string[] = [];
48
+
49
+ // Header
50
+ lines.push("╭─ soly · v" + version + " ──────────────────────────────────────╮");
51
+ lines.push(`│ soly: idle │`);
52
+ lines.push("╰──────────────────────────────────────────────────────────╯");
53
+ lines.push("");
54
+
55
+ // Project state
56
+ lines.push(" Project state");
57
+ lines.push(" ─────────────");
58
+ if (!state.exists) {
59
+ lines.push(" no .agents/ or .soly/ found in cwd");
60
+ lines.push(" → run /soly-init to scaffold");
61
+ } else {
62
+ lines.push(` milestone: ${state.milestone ?? "—"}`);
63
+ lines.push(` current: ${state.currentPosition ?? "ready"}`);
64
+ lines.push(` phases: ${state.phases.length}`);
65
+ if (state.features && state.features.length > 0) {
66
+ lines.push(` features: ${state.features.length}`);
67
+ }
68
+ }
69
+ lines.push("");
70
+
71
+ // Recent decisions (from STATE.md)
72
+ if (state.exists) {
73
+ const decisions = readDecisions(state.solyDir, recentDecisions);
74
+ if (decisions.length > 0) {
75
+ lines.push(" Recent decisions");
76
+ lines.push(" ───────────────");
77
+ for (const d of decisions) {
78
+ lines.push(` ${d}`);
79
+ }
80
+ lines.push("");
81
+ }
82
+ }
83
+
84
+ // Recent notifications
85
+ const notifs = readNotifications(cwd, recentNotifs);
86
+ if (notifs.length > 0) {
87
+ lines.push(" Last notifications");
88
+ lines.push(" ─────────────────");
89
+ for (const n of notifs) {
90
+ const date = n.ts.slice(0, 16).replace("T", " ");
91
+ lines.push(` [${date}] [${n.kind.padEnd(11)}] ${n.title}`);
92
+ }
93
+ lines.push("");
94
+ lines.push(" → /soly-log [N] for full history");
95
+ } else {
96
+ lines.push(" Last notifications");
97
+ lines.push(" ─────────────────");
98
+ lines.push(" (none recorded)");
99
+ }
100
+
101
+ return lines.join("\n");
102
+ }
103
+
104
+ /** Read the Decisions table from STATE.md. Returns formatted lines. */
105
+ function readDecisions(solyDir: string, limit: number): string[] {
106
+ const statePath = path.join(solyDir, "STATE.md");
107
+ let raw: string;
108
+ try {
109
+ raw = readFileSync(statePath, "utf-8");
110
+ } catch {
111
+ return [];
112
+ }
113
+
114
+ // Guard: file is empty or too short to have a Decisions section
115
+ if (raw.trim().length < 20) return [];
116
+
117
+ // Find the Decisions section (graceful: missing → empty, not crash)
118
+ const m = raw.match(/## Decisions\s*\n([\s\S]*?)(?=\n## |\n*$)/);
119
+ if (!m || !m[1]) return [];
120
+
121
+ try {
122
+ const lines = m[1].split("\n").filter((l) => l.startsWith("|") && !l.includes("---"));
123
+ if (lines.length === 0) return [];
124
+
125
+ // Skip header row, take last N
126
+ const rows = lines.slice(1);
127
+ const tail = rows.slice(-limit);
128
+
129
+ return tail.map((row) => {
130
+ const cells = row.split("|").map((c) => c.trim()).filter((c) => c.length > 0);
131
+ if (cells.length < 2) return row;
132
+ const date = (cells[0] ?? "").slice(0, 10);
133
+ const decision = (cells[1] ?? "").slice(0, 50);
134
+ const why = (cells[2] ?? "").slice(0, 40);
135
+ return `${date} ${decision.padEnd(50)} ${why}`;
136
+ });
137
+ } catch {
138
+ return [];
139
+ }
140
+ }