propr-cli 0.8.3 → 0.8.5

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 (44) hide show
  1. package/README.md +4 -4
  2. package/dist/api/relay.js +10 -0
  3. package/dist/assets/env.example.txt +182 -59
  4. package/dist/auth/githubLogin.js +66 -0
  5. package/dist/commands/agentCommands.js +74 -0
  6. package/dist/commands/agentValidation.js +548 -0
  7. package/dist/commands/checkCommands.js +981 -76
  8. package/dist/commands/imageCommands.js +60 -0
  9. package/dist/commands/index.js +3 -0
  10. package/dist/commands/initStack.js +50 -1
  11. package/dist/commands/relayCommands.js +45 -12
  12. package/dist/commands/setup/agents.js +185 -0
  13. package/dist/commands/setup/engine.js +956 -0
  14. package/dist/commands/setup/github.js +181 -0
  15. package/dist/commands/setup/sequential.js +501 -0
  16. package/dist/commands/setup/state.js +242 -0
  17. package/dist/commands/setup/types.js +85 -0
  18. package/dist/commands/setupCommand.js +85 -0
  19. package/dist/commands/stackCommands.js +14 -2
  20. package/dist/commands/systemCommands.js +49 -2
  21. package/dist/commands/tunnelCommand.js +562 -0
  22. package/dist/config/ConfigManager.js +22 -0
  23. package/dist/config/types.js +1 -0
  24. package/dist/index.js +14 -45
  25. package/dist/orchestrator/format.js +46 -0
  26. package/dist/orchestrator/index.js +7 -2
  27. package/dist/orchestrator/manifest.json +12 -11
  28. package/dist/orchestrator/orchestrator.mjs +872 -73
  29. package/dist/tui/AgentTableApp.js +86 -0
  30. package/dist/tui/CheckApp.js +202 -0
  31. package/dist/tui/SetupApp.js +586 -0
  32. package/dist/tui/SetupApp.test.js +172 -0
  33. package/dist/tui/app.js +84 -0
  34. package/dist/tui/render.js +28 -2
  35. package/dist/utils/envFile.js +45 -0
  36. package/dist/vendor/shared/githubEventIntakeMode.js +41 -0
  37. package/dist/vendor/shared/index.js +17 -0
  38. package/dist/vendor/shared/intakeModePrerequisites.js +76 -0
  39. package/dist/vendor/shared/modelDefinitions.js +4 -4
  40. package/dist/vendor/shared/proprCompatibility.js +70 -0
  41. package/dist/vendor/shared/proprServiceUrls.js +124 -0
  42. package/dist/vendor/shared/statusKeys.js +14 -0
  43. package/dist/vendor/shared/validateRoutingUrl.js +46 -0
  44. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { readFileSync } from "fs";
5
5
  import { dirname, join } from "path";
6
6
  import { fileURLToPath } from "url";
7
7
  import { createConfigManager } from "./config/index.js";
8
- import { createIssueCommand, createPlanCommand, createTaskCommand, createRepoCommand, createAgentCommand, createSettingCommand, createLogCommand, createTodoCommand, createRemoteStatusCommand, createQueueCommand, createInitCommand, createCheckCommand, createStartCommand, createStackStatusCommand, createStopCommand, createUiCommand, createDocsCommand, createTankCommand, createRelayCommand, runChecks, printChecks, STACK_CONFIG_CHECK_NAME, } from "./commands/index.js";
8
+ import { createIssueCommand, createPlanCommand, createTaskCommand, createRepoCommand, createAgentCommand, createSettingCommand, createLogCommand, createTodoCommand, createRemoteStatusCommand, createQueueCommand, createInitCommand, createSetupCommand, createCheckCommand, createImagesCommand, createStartCommand, createStackStatusCommand, createStopCommand, createUiCommand, createDocsCommand, createTunnelCommand, createTankCommand, createRelayCommand, runChecks, printChecks, STACK_CONFIG_CHECK_NAME, } from "./commands/index.js";
9
9
  // Re-export configuration module for programmatic use
10
10
  export { ConfigManager, createConfigManager, DEFAULT_CONFIG, } from "./config/index.js";
11
11
  // Re-export API module for programmatic use
@@ -31,6 +31,7 @@ drive the backend (plans, issues, tasks, repos, agents).
31
31
  Quick Start (local stack):
32
32
  $ propr Verify the environment (same as 'propr check')
33
33
  $ propr init stack Scaffold .env + data/logs/repos, detect agents
34
+ $ propr images pull Pull stack images without starting
34
35
  $ propr start Start the stack with a live dashboard
35
36
  $ propr status Show local stack status
36
37
  $ propr stop Stop the stack
@@ -57,7 +58,7 @@ Examples:
57
58
  $ propr remote-status
58
59
 
59
60
  Command Groups:
60
- Control Plane: check, init [repo|stack], start, status, stop, ui, docs, tank
61
+ Control Plane: check, images, init [repo|stack], start, status, stop, ui, docs, tunnel, tank
61
62
  GitHub Relay: relay [enroll|list|revoke]
62
63
  Configuration: remote, use, login, logout
63
64
  Plans: plan [create|list|get|delete|abort]
@@ -149,53 +150,18 @@ Examples:
149
150
  console.log(`Token saved to: ${configManager.getConfigFilePath()}`);
150
151
  return;
151
152
  }
152
- // Interactive flow via gh CLI
153
- const { execSync, spawnSync } = await import("child_process");
154
- // Check if gh is installed
155
- try {
156
- execSync("gh --version", { stdio: "ignore" });
157
- }
158
- catch {
159
- console.error("Error: GitHub CLI (gh) is not installed.");
160
- console.log("");
161
- console.log("Install it from: https://cli.github.com");
162
- console.log("");
163
- console.log("Or provide a token directly:");
164
- console.log(" $ propr login <token>");
165
- process.exit(1);
166
- }
167
- // Try to get an existing token
168
- try {
169
- const existingToken = execSync("gh auth token", { encoding: "utf-8", stdio: ["pipe", "pipe", "ignore"] }).trim();
170
- if (existingToken) {
171
- await configManager.setGithubToken(existingToken);
172
- console.log("Authenticated using existing gh CLI session.");
173
- console.log(`Token saved to: ${configManager.getConfigFilePath()}`);
174
- return;
175
- }
176
- }
177
- catch {
178
- // Not logged in yet — proceed to interactive login
179
- }
180
- // Launch interactive gh auth login
181
- console.log("No existing gh session found. Starting interactive login...");
182
- console.log("");
183
- const result = spawnSync("gh", ["auth", "login", "-s", "repo,read:org"], {
184
- stdio: "inherit",
153
+ // Interactive flow via the gh CLI (shared with `propr setup`).
154
+ const { loginWithGithubCli } = await import("./auth/githubLogin.js");
155
+ const result = await loginWithGithubCli(configManager, {
156
+ interactive: true,
157
+ onLog: (line) => console.log(line),
185
158
  });
186
- if (result.status !== 0) {
187
- console.error("Error: GitHub login failed or was cancelled.");
188
- process.exit(1);
189
- }
190
- // Grab the token after successful login
191
- const ghToken = execSync("gh auth token", { encoding: "utf-8", stdio: ["pipe", "pipe", "ignore"] }).trim();
192
- if (!ghToken) {
193
- console.error("Error: Could not retrieve token after login.");
159
+ if (!result.ok) {
160
+ console.error(`Error: ${result.message}`);
194
161
  process.exit(1);
195
162
  }
196
- await configManager.setGithubToken(ghToken);
197
163
  console.log("");
198
- console.log("Authentication successful!");
164
+ console.log(result.message);
199
165
  console.log(`Token saved to: ${configManager.getConfigFilePath()}`);
200
166
  }
201
167
  catch (error) {
@@ -230,15 +196,18 @@ Example:
230
196
  });
231
197
  // Control-plane commands (local Docker stack)
232
198
  program.addCommand(createCheckCommand());
199
+ program.addCommand(createImagesCommand());
233
200
  program.addCommand(createStartCommand());
234
201
  program.addCommand(createStackStatusCommand());
235
202
  program.addCommand(createStopCommand());
236
203
  program.addCommand(createUiCommand());
237
204
  program.addCommand(createDocsCommand());
205
+ program.addCommand(createTunnelCommand());
238
206
  program.addCommand(createTankCommand());
239
207
  program.addCommand(createRelayCommand());
240
208
  // Setup + backend client command groups
241
209
  program.addCommand(createInitCommand());
210
+ program.addCommand(createSetupCommand());
242
211
  program.addCommand(createPlanCommand());
243
212
  program.addCommand(createIssueCommand());
244
213
  program.addCommand(createTaskCommand());
@@ -2,6 +2,7 @@
2
2
  * Shared rendering for stack status — used by `propr status` (one-shot) and the
3
3
  * `propr start` TUI's non-TTY fallback.
4
4
  */
5
+ import { proprTunnelEndpoints } from "../vendor/shared/index.js";
5
6
  export function stateGlyph(s) {
6
7
  if (!s.exists)
7
8
  return "·";
@@ -29,3 +30,48 @@ export function renderStatusTable(status) {
29
30
  }
30
31
  return lines.join("\n");
31
32
  }
33
+ /**
34
+ * A short "where the hosted UI reaches this stack" summary for startup output.
35
+ * Lists the concrete routed endpoints rather than the base URL, and notes the
36
+ * root 404, so nothing implies the root URL is an API/health target. Returns an
37
+ * empty array when there is no public URL to advertise.
38
+ */
39
+ export function renderTunnelEndpointSummary(publicApiUrl) {
40
+ if (!publicApiUrl)
41
+ return [];
42
+ const { apiStatus, socketIo } = proprTunnelEndpoints(publicApiUrl);
43
+ return [
44
+ "Tunnel is up — the hosted UI reaches this stack at:",
45
+ ` API: ${apiStatus}`,
46
+ ` Socket.IO: ${socketIo}`,
47
+ " Root URL intentionally returns 404.",
48
+ ];
49
+ }
50
+ /** A yes/no/unknown glyph+label for a tri-state tunnel field. */
51
+ function tunnelFlag(value) {
52
+ if (value === null)
53
+ return "· unknown";
54
+ return value ? "● yes" : "○ no";
55
+ }
56
+ /** Tunnel diagnostics section as a string (see TunnelStatus). */
57
+ export function renderTunnelSection(t) {
58
+ const lines = [];
59
+ lines.push("Tunnel");
60
+ lines.push("─".repeat(60));
61
+ lines.push(` enabled ${tunnelFlag(t.enabled)}`);
62
+ lines.push(` configured ${tunnelFlag(t.configured)}`);
63
+ lines.push(` running ${tunnelFlag(t.running)}`);
64
+ if (t.publicApiUrl) {
65
+ // Show the concrete endpoints propr-routing forwards, not the base URL as if
66
+ // it were a health target — the root path intentionally 404s through the
67
+ // tunnel. `reachable` reflects the /api/status probe.
68
+ const { apiStatus, socketIo } = proprTunnelEndpoints(t.publicApiUrl);
69
+ lines.push(` API ${apiStatus}`);
70
+ lines.push(` Socket.IO ${socketIo}`);
71
+ }
72
+ else {
73
+ lines.push(` public URL —`);
74
+ }
75
+ lines.push(` reachable ${tunnelFlag(t.reachable)} (probes /api/status)`);
76
+ return lines.join("\n");
77
+ }
@@ -77,8 +77,9 @@ export function resolveStackRoot(configManager, flagRoot) {
77
77
  /**
78
78
  * Convenience: load the orchestrator and resolve a host config for the given
79
79
  * (or resolved) stack root. When a ConfigManager is provided, persisted CLI
80
- * settings (docsEnabled) are forwarded as overrides so `propr start` honors
81
- * `propr docs on`. Note: uiEnabled is read directly from ConfigManager at
80
+ * settings (docsEnabled, tunnelEnabled) are forwarded as overrides so `propr
81
+ * start` honors `propr docs on` and `propr tunnel on`. Note: uiEnabled is read
82
+ * directly from ConfigManager at
82
83
  * call sites (e.g. render.ts) and passed to startStack(); it is not part of
83
84
  * the resolved config because resolveConfig does not consume it.
84
85
  */
@@ -96,6 +97,10 @@ export async function getHostConfig(opts) {
96
97
  if (docsExplicit !== undefined) {
97
98
  cliOverrides.docsEnabled = docsExplicit;
98
99
  }
100
+ const tunnelExplicit = opts.configManager.get("tunnelEnabled");
101
+ if (tunnelExplicit !== undefined) {
102
+ cliOverrides.uiTunnelEnabled = tunnelExplicit;
103
+ }
99
104
  }
100
105
  const cfg = orch.resolveHostConfig({ rootDir, env: process.env, manifestPath, cliOverrides });
101
106
  return { orch, cfg, rootDir };
@@ -1,16 +1,17 @@
1
1
  {
2
- "version": "0.8.3",
3
- "git_sha": "ce5f5d5f",
2
+ "version": "0.8.5",
3
+ "git_sha": "45e9ed5a",
4
4
  "registry": "propr",
5
5
  "images": {
6
- "app": "propr/app:0.8.2",
7
- "ui": "propr/ui:0.8.2",
8
- "docs": "propr/docs:0.8.2",
9
- "agent-claude": "propr/agent-claude:0.8.2",
10
- "agent-codex": "propr/agent-codex:0.8.2",
11
- "agent-antigravity": "propr/agent-antigravity:0.8.2",
12
- "agent-opencode": "propr/agent-opencode:0.8.2",
13
- "agent-vibe": "propr/agent-vibe:0.8.2",
14
- "redis": "redis:7-alpine"
6
+ "app": "propr/app:0.8.5",
7
+ "ui": "propr/ui:0.8.5",
8
+ "docs": "propr/docs:0.8.5",
9
+ "agent-claude": "propr/agent-claude:0.8.5",
10
+ "agent-codex": "propr/agent-codex:0.8.5",
11
+ "agent-antigravity": "propr/agent-antigravity:0.8.5",
12
+ "agent-opencode": "propr/agent-opencode:0.8.5",
13
+ "agent-vibe": "propr/agent-vibe:0.8.5",
14
+ "redis": "redis:7-alpine",
15
+ "cloudflared": "cloudflare/cloudflared:2024.12.2"
15
16
  }
16
17
  }