propr-cli 0.8.3

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 (64) hide show
  1. package/README.md +549 -0
  2. package/dist/api/agentTank.js +27 -0
  3. package/dist/api/agents.js +201 -0
  4. package/dist/api/client.js +284 -0
  5. package/dist/api/errors.js +145 -0
  6. package/dist/api/implement.js +147 -0
  7. package/dist/api/index.js +26 -0
  8. package/dist/api/logs.js +59 -0
  9. package/dist/api/plans.js +160 -0
  10. package/dist/api/relay.js +73 -0
  11. package/dist/api/repos.js +243 -0
  12. package/dist/api/settings.js +219 -0
  13. package/dist/api/system.js +53 -0
  14. package/dist/api/tasks.js +140 -0
  15. package/dist/api/todos.js +77 -0
  16. package/dist/api/types.js +6 -0
  17. package/dist/assets/.env.example +183 -0
  18. package/dist/assets/env.example.txt +198 -0
  19. package/dist/commands/agentCommands.js +405 -0
  20. package/dist/commands/checkCommands.js +384 -0
  21. package/dist/commands/implementCommands.js +178 -0
  22. package/dist/commands/index.js +22 -0
  23. package/dist/commands/initCommands.js +167 -0
  24. package/dist/commands/initStack.js +193 -0
  25. package/dist/commands/logCommands.js +170 -0
  26. package/dist/commands/planCommands.js +552 -0
  27. package/dist/commands/relayCommands.js +149 -0
  28. package/dist/commands/repoCommands.js +526 -0
  29. package/dist/commands/settingCommands.js +237 -0
  30. package/dist/commands/stackCommands.js +86 -0
  31. package/dist/commands/startCommand.js +36 -0
  32. package/dist/commands/systemCommands.js +221 -0
  33. package/dist/commands/tankCommands.js +55 -0
  34. package/dist/commands/taskCommands.js +554 -0
  35. package/dist/commands/todoCommands.js +620 -0
  36. package/dist/commands/uiDocsCommands.js +69 -0
  37. package/dist/config/ConfigManager.js +360 -0
  38. package/dist/config/index.js +8 -0
  39. package/dist/config/types.js +16 -0
  40. package/dist/index.js +276 -0
  41. package/dist/orchestrator/format.js +31 -0
  42. package/dist/orchestrator/index.js +102 -0
  43. package/dist/orchestrator/manifest.json +16 -0
  44. package/dist/orchestrator/orchestrator.mjs +798 -0
  45. package/dist/orchestrator/types.js +10 -0
  46. package/dist/tui/StartApp.js +175 -0
  47. package/dist/tui/app.js +9 -0
  48. package/dist/tui/render.js +87 -0
  49. package/dist/utils/envFile.js +65 -0
  50. package/dist/utils/index.js +8 -0
  51. package/dist/utils/io.js +186 -0
  52. package/dist/utils/parseState.js +14 -0
  53. package/dist/utils/resolveProject.js +50 -0
  54. package/dist/vendor/shared/demoMode.js +6 -0
  55. package/dist/vendor/shared/events.js +30 -0
  56. package/dist/vendor/shared/githubAuthMode.js +35 -0
  57. package/dist/vendor/shared/index.js +15 -0
  58. package/dist/vendor/shared/labelUtils.js +32 -0
  59. package/dist/vendor/shared/modelDefinitions.js +146 -0
  60. package/dist/vendor/shared/reviewPrompt.js +18 -0
  61. package/dist/vendor/shared/usageTypes.js +13 -0
  62. package/dist/vendor/shared/userWhitelist.js +30 -0
  63. package/dist/vendor/shared/validateRelayUrl.js +21 -0
  64. package/package.json +31 -0
@@ -0,0 +1,35 @@
1
+ /**
2
+ * GitHub auth mode inference, shared by the backend (@propr/core githubAuth)
3
+ * and the CLI (`propr check`) so the two can't drift.
4
+ *
5
+ * Auth is configured one of three ways:
6
+ * demo — no GitHub access
7
+ * relay — fetch installation tokens from a vendor relay (shared-app path)
8
+ * app — mint installation tokens locally from the App private key (own-app)
9
+ * An explicit GH_AUTH_MODE overrides the inference.
10
+ */
11
+ export function resolveGithubAuthMode(env) {
12
+ const warnings = [];
13
+ if (env.demoMode)
14
+ return { mode: 'demo', warnings };
15
+ const explicit = (env.ghAuthMode || '').trim().toLowerCase();
16
+ if (explicit === 'demo') {
17
+ warnings.push('GH_AUTH_MODE=demo only disables GitHub auth. Set PROPR_DEMO_MODE=true for full demo-mode behavior across the API and workers.');
18
+ return { mode: 'demo', warnings };
19
+ }
20
+ if (explicit === 'relay')
21
+ return { mode: 'relay', warnings };
22
+ if (explicit === 'app')
23
+ return { mode: 'app', warnings };
24
+ if (explicit) {
25
+ warnings.push(`GH_AUTH_MODE="${env.ghAuthMode}" is not a recognized value (expected "app", "relay", or "demo"). Falling back to auto-detection.`);
26
+ }
27
+ // Inferred relay requires both URL and token so a stray placeholder URL
28
+ // doesn't shadow a fully valid GitHub App configuration.
29
+ if (env.relayUrl && env.relayToken)
30
+ return { mode: 'relay', warnings };
31
+ if (env.appId && env.privateKeyPath && env.installationId)
32
+ return { mode: 'app', warnings };
33
+ return { mode: 'none', warnings };
34
+ }
35
+ //# sourceMappingURL=githubAuthMode.js.map
@@ -0,0 +1,15 @@
1
+ // Export all model definitions
2
+ export { AGENT_TYPES, CLAUDE_MODELS, CODEX_MODELS, ANTIGRAVITY_MODELS, OPENCODE_MODELS, VIBE_MODELS, ALL_MODELS, AGENT_MODELS, AGENT_DISPLAY, AGENT_DISPLAY_ORDER, MODEL_INFO_MAP, MODEL_SHORT_NAMES, AGENT_DEFAULTS, typeBadgeColors, } from './modelDefinitions.js';
3
+ // Export event definitions for real-time updates
4
+ export { TASK_UPDATE, DRAFT_UPDATE, PLAN_STEP_UPDATE, INDEXING_UPDATE, TASK_LIVE_UPDATE, QUEUE_STATS_UPDATE, REDIS_CHANNELS, } from './events.js';
5
+ export { DEMO_MODE_READ_ONLY_CODE, parseTruthyEnvValue } from './demoMode.js';
6
+ // Export user whitelist helpers
7
+ export { getGithubUserWhitelist, isGithubUserWhitelisted, } from './userWhitelist.js';
8
+ // Export relay URL validation
9
+ export { validateRelayUrl } from './validateRelayUrl.js';
10
+ // Export GitHub auth mode inference (shared by backend boot and `propr check`)
11
+ export { resolveGithubAuthMode, } from './githubAuthMode.js';
12
+ export { shortHash, buildDynamicLlmLabel, MAX_GITHUB_LABEL_LENGTH } from './labelUtils.js';
13
+ // Export the default review guidance (the overridable part of the /review prompt)
14
+ export { DEFAULT_REVIEW_GUIDANCE } from './reviewPrompt.js';
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,32 @@
1
+ // GitHub's hard limit on label name length
2
+ export const MAX_GITHUB_LABEL_LENGTH = 50;
3
+ // 32-bit FNV-1a hash, base36-encoded. Used for routing — not cryptographic.
4
+ export function shortHash(value) {
5
+ let hash = 2166136261;
6
+ for (let index = 0; index < value.length; index++) {
7
+ hash ^= value.charCodeAt(index);
8
+ hash = Math.imul(hash, 16777619);
9
+ }
10
+ return (hash >>> 0).toString(36);
11
+ }
12
+ // `~` separator is an intentional public contract — these labels are persisted on GitHub and resolved later
13
+ export function buildDynamicLlmLabel(agentKey, modelId) {
14
+ const canonicalLabel = `llm-${agentKey}~${modelId}`;
15
+ if (canonicalLabel.length <= MAX_GITHUB_LABEL_LENGTH)
16
+ return canonicalLabel;
17
+ const hash = shortHash(modelId);
18
+ const maxAliasLength = Math.max(1, MAX_GITHUB_LABEL_LENGTH - `llm-~-x-${hash}`.length);
19
+ const sanitizedAlias = agentKey
20
+ .replace(/[^a-zA-Z0-9_.-]/g, '-')
21
+ .slice(0, maxAliasLength)
22
+ .replace(/[^a-zA-Z0-9]+$/, '');
23
+ const labelAlias = sanitizedAlias || 'agent'.slice(0, maxAliasLength);
24
+ const prefixBudget = MAX_GITHUB_LABEL_LENGTH - `llm-${labelAlias}~-${hash}`.length;
25
+ const fallbackPrefix = 'model'.slice(0, Math.max(1, prefixBudget));
26
+ const modelPrefix = modelId
27
+ .replace(/[^a-zA-Z0-9_.-]/g, '-')
28
+ .slice(0, Math.max(1, prefixBudget))
29
+ .replace(/[^a-zA-Z0-9]+$/, '');
30
+ return `llm-${labelAlias}~${modelPrefix || fallbackPrefix}-${hash}`;
31
+ }
32
+ //# sourceMappingURL=labelUtils.js.map
@@ -0,0 +1,146 @@
1
+ // Shared model definitions for AI agents
2
+ // This file provides a single source of truth for model information
3
+ // Both backend (packages/core) and frontend (propr-ui) import from this package
4
+ export const AGENT_TYPES = ['claude', 'codex', 'antigravity', 'opencode', 'vibe'];
5
+ // Claude models (newest first within each tier, then by capability: Opus > Sonnet > Haiku)
6
+ // 4.8/4.7/4.6 models require newer Claude Code versions; 4.5 models work with older versions
7
+ export const CLAUDE_MODELS = [
8
+ // Claude Fable 5 (top tier, above Opus)
9
+ { id: 'claude-fable-5', name: 'Claude Fable 5', shortName: 'Claude Fable 5', shortAlias: 'fable', githubLabel: 'llm-claude-fable', contextWindow: '1M', maxTokens: 1000000, openRouterId: 'anthropic/claude-fable-5', minAgentVersion: '2.1.170' },
10
+ // Claude 4.8 series
11
+ { id: 'claude-opus-4-8', name: 'Claude Opus 4.8', shortName: 'Claude Opus 4.8', shortAlias: 'opus48', githubLabel: 'llm-claude-opus48', contextWindow: '1M', maxTokens: 1000000, openRouterId: 'anthropic/claude-opus-4.8' },
12
+ // Claude 4.7 series
13
+ { id: 'claude-opus-4-7', name: 'Claude Opus 4.7', shortName: 'Claude Opus 4.7', shortAlias: 'opus47', githubLabel: 'llm-claude-opus47', contextWindow: '1M', maxTokens: 1000000, openRouterId: 'anthropic/claude-opus-4.7' },
14
+ // Claude 4.6 series (1M context for Opus/Sonnet)
15
+ { id: 'claude-opus-4-6', name: 'Claude Opus 4.6', shortName: 'Claude Opus 4.6', shortAlias: 'opus46', githubLabel: 'llm-claude-opus46', contextWindow: '1M', maxTokens: 1000000, openRouterId: 'anthropic/claude-opus-4.6', minAgentVersion: '2.1.50' },
16
+ { id: 'claude-sonnet-4-6', name: 'Claude Sonnet 4.6', shortName: 'Claude Sonnet 4.6', shortAlias: 'sonnet46', githubLabel: 'llm-claude-sonnet46', contextWindow: '1M', maxTokens: 1000000, openRouterId: 'anthropic/claude-sonnet-4.6', minAgentVersion: '2.1.45' },
17
+ // Claude 4.5 series (200K context, works with all Claude Code versions)
18
+ { id: 'claude-opus-4-5-20251101', name: 'Claude Opus 4.5', shortName: 'Claude Opus 4.5', shortAlias: 'opus45', githubLabel: 'llm-claude-opus45', contextWindow: '200K', maxTokens: 200000, openRouterId: 'anthropic/claude-opus-4.5' },
19
+ { id: 'claude-sonnet-4-5-20250929', name: 'Claude Sonnet 4.5', shortName: 'Claude Sonnet 4.5', shortAlias: 'sonnet45', githubLabel: 'llm-claude-sonnet45', contextWindow: '200K', maxTokens: 200000, openRouterId: 'anthropic/claude-sonnet-4.5' },
20
+ { id: 'claude-haiku-4-5-20251001', name: 'Claude Haiku 4.5', shortName: 'Claude Haiku', shortAlias: 'haiku', githubLabel: 'llm-claude-haiku', contextWindow: '200K', maxTokens: 200000, openRouterId: 'anthropic/claude-haiku-4.5' },
21
+ ];
22
+ // Codex (OpenAI) models - availability depends on account type (ChatGPT login vs API key)
23
+ // Recommended: gpt-5.5 (default), gpt-5.4-mini/nano (fast/subagents), gpt-5.3-codex (agentic coding)
24
+ export const CODEX_MODELS = [
25
+ { id: 'gpt-5.5', name: 'GPT-5.5', shortName: 'GPT-5.5', shortAlias: 'gpt55', githubLabel: 'llm-codex-gpt55', contextWindow: '1M', maxTokens: 1050000, openRouterId: 'openai/gpt-5.5' },
26
+ { id: 'gpt-5.5-pro', name: 'GPT-5.5 Pro', shortName: 'GPT-5.5 Pro', shortAlias: 'gpt55-pro', githubLabel: 'llm-codex-gpt55-pro', contextWindow: '1M', maxTokens: 1050000, openRouterId: 'openai/gpt-5.5-pro' },
27
+ { id: 'gpt-5.4', name: 'GPT-5.4', shortName: 'GPT-5.4', shortAlias: 'gpt54', githubLabel: 'llm-codex-gpt54', contextWindow: '1M', maxTokens: 1050000, openRouterId: 'openai/gpt-5.4' },
28
+ { id: 'gpt-5.4-pro', name: 'GPT-5.4 Pro', shortName: 'GPT-5.4 Pro', shortAlias: 'gpt54-pro', githubLabel: 'llm-codex-gpt54-pro', contextWindow: '1M', maxTokens: 1050000, openRouterId: 'openai/gpt-5.4-pro' },
29
+ { id: 'gpt-5.4-mini', name: 'GPT-5.4 Mini', shortName: 'GPT-5.4 Mini', shortAlias: 'gpt54-mini', githubLabel: 'llm-codex-gpt54-mini', contextWindow: '400K', maxTokens: 400000, openRouterId: 'openai/gpt-5.4-mini' },
30
+ { id: 'gpt-5.4-nano', name: 'GPT-5.4 Nano', shortName: 'GPT-5.4 Nano', shortAlias: 'gpt54-nano', githubLabel: 'llm-codex-gpt54-nano', contextWindow: '400K', maxTokens: 400000, openRouterId: 'openai/gpt-5.4-nano' },
31
+ { id: 'gpt-5.3-codex', name: 'GPT-5.3 Codex', shortName: 'GPT-5.3 Codex', shortAlias: 'gpt53-codex', githubLabel: 'llm-codex-gpt53-codex', contextWindow: '400K', maxTokens: 400000, openRouterId: 'openai/gpt-5.3-codex' },
32
+ { id: 'gpt-5.3-codex-spark', name: 'GPT-5.3 Codex Spark', shortName: 'Codex Spark', shortAlias: 'codex-spark', githubLabel: 'llm-codex-spark', contextWindow: '400K', maxTokens: 400000, openRouterId: 'openai/gpt-5.3-codex-spark' },
33
+ { id: 'gpt-5.2', name: 'GPT-5.2', shortName: 'GPT-5.2', shortAlias: 'gpt52', githubLabel: 'llm-codex-gpt52', contextWindow: '400K', maxTokens: 400000, openRouterId: 'openai/gpt-5.2' },
34
+ { id: 'gpt-5-mini', name: 'GPT-5 Mini', shortName: 'GPT-5 Mini', shortAlias: 'gpt5-mini', githubLabel: 'llm-codex-gpt5-mini', contextWindow: '400K', maxTokens: 400000, openRouterId: 'openai/gpt-5-mini' },
35
+ { id: 'gpt-5-nano', name: 'GPT-5 Nano', shortName: 'GPT-5 Nano', shortAlias: 'gpt5-nano', githubLabel: 'llm-codex-gpt5-nano', contextWindow: '400K', maxTokens: 400000, openRouterId: 'openai/gpt-5-nano' },
36
+ ];
37
+ // Antigravity models. Antigravity can route to multiple model families, so
38
+ // these IDs are intentionally namespaced instead of treating every model as a
39
+ // Google/Gemini model.
40
+ export const ANTIGRAVITY_MODELS = [
41
+ { id: 'antigravity-gemini-3.5-flash-medium', name: 'Antigravity Gemini 3.5 Flash Medium', shortName: 'Gemini 3.5 Flash Medium', shortAlias: 'flash-medium', githubLabel: 'llm-antigravity-flash-medium', contextWindow: '1M', maxTokens: 1000000, openRouterId: 'google/gemini-3.5-flash' },
42
+ { id: 'antigravity-gemini-3.5-flash-high', name: 'Antigravity Gemini 3.5 Flash High', shortName: 'Gemini 3.5 Flash High', shortAlias: 'flash-high', githubLabel: 'llm-antigravity-flash-high', contextWindow: '1M', maxTokens: 1000000, openRouterId: 'google/gemini-3.5-flash' },
43
+ { id: 'antigravity-gemini-3.5-flash-low', name: 'Antigravity Gemini 3.5 Flash Low', shortName: 'Gemini 3.5 Flash Low', shortAlias: 'flash-low', githubLabel: 'llm-antigravity-flash-low', contextWindow: '1M', maxTokens: 1000000, openRouterId: 'google/gemini-3.5-flash' },
44
+ { id: 'antigravity-gemini-3.1-pro-low', name: 'Antigravity Gemini 3.1 Pro Low', shortName: 'Gemini 3.1 Pro Low', shortAlias: 'pro-low', githubLabel: 'llm-antigravity-pro-low', contextWindow: '1M', maxTokens: 1000000, openRouterId: 'google/gemini-3.1-pro-preview' },
45
+ { id: 'antigravity-gemini-3.1-pro-high', name: 'Antigravity Gemini 3.1 Pro High', shortName: 'Gemini 3.1 Pro High', shortAlias: 'pro-high', githubLabel: 'llm-antigravity-pro-high', contextWindow: '1M', maxTokens: 1000000, openRouterId: 'google/gemini-3.1-pro-preview' },
46
+ { id: 'antigravity-claude-sonnet-4.6-thinking', name: 'Antigravity Claude Sonnet 4.6 Thinking', shortName: 'Claude Sonnet 4.6 Thinking', shortAlias: 'sonnet46-thinking', githubLabel: 'llm-antigravity-sonnet46-thinking', contextWindow: '1M', maxTokens: 1000000, openRouterId: 'anthropic/claude-sonnet-4.6' },
47
+ { id: 'antigravity-claude-opus-4.6-thinking', name: 'Antigravity Claude Opus 4.6 Thinking', shortName: 'Claude Opus 4.6 Thinking', shortAlias: 'opus46-thinking', githubLabel: 'llm-antigravity-opus46-thinking', contextWindow: '1M', maxTokens: 1000000, openRouterId: 'anthropic/claude-opus-4.6' },
48
+ { id: 'antigravity-gpt-oss-120b-medium', name: 'Antigravity GPT-OSS 120B Medium', shortName: 'GPT-OSS 120B Medium', shortAlias: 'gpt-oss-120b', githubLabel: 'llm-antigravity-gpt-oss-120b', contextWindow: '1M', maxTokens: 1000000, openRouterId: 'openai/gpt-oss-120b' },
49
+ ];
50
+ // OpenCode built-in free models. IDs are namespaced for ProPR and converted
51
+ // back to OpenCode's provider/model syntax at CLI execution time.
52
+ // These are available from `opencode models` without provider login.
53
+ export const OPENCODE_MODELS = [
54
+ { id: 'opencode-minimax-m3-free', name: 'MiniMax M3 Free', shortName: 'MiniMax M3 Free', shortAlias: 'minimax-m3-free', githubLabel: 'llm-opencode-minimax-m3-free', contextWindow: '200K', maxTokens: 200000, openRouterId: 'minimax/minimax-m3' },
55
+ { id: 'opencode-deepseek-v4-flash-free', name: 'DeepSeek V4 Flash Free', shortName: 'DeepSeek V4 Flash Free', shortAlias: 'deepseek-v4-flash-free', githubLabel: 'llm-opencode-deepseek-v4-flash-free', contextWindow: '200K', maxTokens: 200000, openRouterId: 'deepseek/deepseek-v4-flash' },
56
+ { id: 'opencode-mimo-v2.5-free', name: 'MiMo V2.5 Free', shortName: 'MiMo V2.5 Free', shortAlias: 'mimo-v25-free', githubLabel: 'llm-opencode-mimo-v25-free', contextWindow: '200K', maxTokens: 200000, openRouterId: 'xiaomi/mimo-v2.5' },
57
+ { id: 'opencode-nemotron-3-ultra-free', name: 'Nemotron 3 Ultra Free', shortName: 'Nemotron 3 Ultra Free', shortAlias: 'nemotron-3-ultra-free', githubLabel: 'llm-opencode-nemotron-3-ultra-free', contextWindow: '1M', maxTokens: 1000000, openRouterId: 'nvidia/nemotron-3-ultra-550b-a55b' },
58
+ { id: 'opencode-big-pickle', name: 'Big Pickle', shortName: 'Big Pickle', shortAlias: 'big-pickle', githubLabel: 'llm-opencode-big-pickle', contextWindow: '200K', maxTokens: 200000, openRouterId: 'opencode/big-pickle' },
59
+ ];
60
+ // Mistral Vibe coding models
61
+ // Available models from `vibe /model`: mistral-medium-3.5, devstral-small, local
62
+ export const VIBE_MODELS = [
63
+ { id: 'mistral-medium-3.5', name: 'Mistral Medium 3.5', shortName: 'Mistral Medium', shortAlias: 'mistral', githubLabel: 'llm-vibe-mistral', contextWindow: '256K', maxTokens: 256000, openRouterId: 'mistralai/mistral-medium-3-5' },
64
+ { id: 'devstral-small', name: 'Devstral Small', shortName: 'Devstral Small', shortAlias: 'devstral', githubLabel: 'llm-vibe-devstral', contextWindow: '256K', maxTokens: 256000, openRouterId: 'mistralai/devstral-2512' },
65
+ ];
66
+ // All models combined
67
+ export const ALL_MODELS = [...CLAUDE_MODELS, ...CODEX_MODELS, ...ANTIGRAVITY_MODELS, ...OPENCODE_MODELS, ...VIBE_MODELS];
68
+ // Map of agent types to their models
69
+ export const AGENT_MODELS = {
70
+ claude: CLAUDE_MODELS,
71
+ codex: CODEX_MODELS,
72
+ antigravity: ANTIGRAVITY_MODELS,
73
+ opencode: OPENCODE_MODELS,
74
+ vibe: VIBE_MODELS,
75
+ };
76
+ export const AGENT_DISPLAY = {
77
+ claude: { label: 'Claude', order: 10 },
78
+ antigravity: { label: 'Antigravity', order: 20 },
79
+ codex: { label: 'Codex (OpenAI)', order: 30 },
80
+ opencode: { label: 'OpenCode', order: 40 },
81
+ vibe: { label: 'Vibe', order: 50 },
82
+ };
83
+ export const AGENT_DISPLAY_ORDER = Object.keys(AGENT_DISPLAY)
84
+ .sort((a, b) => AGENT_DISPLAY[a].order - AGENT_DISPLAY[b].order);
85
+ // Lookup map for all models by ID
86
+ export const MODEL_INFO_MAP = {};
87
+ ALL_MODELS.forEach(m => {
88
+ MODEL_INFO_MAP[m.id] = m;
89
+ });
90
+ // Generate MODEL_SHORT_NAMES from MODEL_INFO_MAP for backwards compatibility
91
+ export const MODEL_SHORT_NAMES = {};
92
+ ALL_MODELS.forEach(m => {
93
+ MODEL_SHORT_NAMES[m.id] = m.shortName;
94
+ });
95
+ // Agent default configurations
96
+ export const AGENT_DEFAULTS = {
97
+ claude: {
98
+ dockerImage: 'propr/agent-claude:latest',
99
+ configPath: '~/.claude',
100
+ defaultModels: CLAUDE_MODELS.map(m => m.id),
101
+ defaultAlias: 'claude',
102
+ npmPackage: '@anthropic-ai/claude-code',
103
+ defaultCliVersion: '2.1.170'
104
+ },
105
+ codex: {
106
+ dockerImage: 'propr/agent-codex:latest',
107
+ configPath: '~/.codex',
108
+ defaultModels: CODEX_MODELS.map(m => m.id),
109
+ defaultAlias: 'codex',
110
+ npmPackage: '@openai/codex',
111
+ defaultCliVersion: '0.137.0'
112
+ },
113
+ antigravity: {
114
+ dockerImage: 'propr/agent-antigravity:latest',
115
+ configPath: '~/.gemini',
116
+ defaultModels: ANTIGRAVITY_MODELS.map(m => m.id),
117
+ defaultAlias: 'antigravity',
118
+ npmPackage: 'https://antigravity.google/cli/install.sh',
119
+ defaultCliVersion: 'latest'
120
+ },
121
+ opencode: {
122
+ dockerImage: 'propr/agent-opencode:latest',
123
+ configPath: '~/.config/opencode',
124
+ defaultModels: OPENCODE_MODELS.map(m => m.id),
125
+ defaultAlias: 'opencode',
126
+ npmPackage: 'opencode-ai',
127
+ defaultCliVersion: '1.16.2'
128
+ },
129
+ vibe: {
130
+ dockerImage: 'propr/agent-vibe:latest',
131
+ configPath: '~/.vibe',
132
+ defaultModels: VIBE_MODELS.map(m => m.id),
133
+ defaultAlias: 'vibe',
134
+ npmPackage: 'mistral-vibe',
135
+ defaultCliVersion: '2.12.1'
136
+ }
137
+ };
138
+ // Badge colors for each agent type (for UI)
139
+ export const typeBadgeColors = {
140
+ claude: 'bg-orange-100 text-orange-800 border-orange-300',
141
+ codex: 'bg-green-100 text-green-800 border-green-300',
142
+ antigravity: 'bg-violet-100 text-violet-800 border-violet-300',
143
+ opencode: 'bg-cyan-100 text-cyan-800 border-cyan-300',
144
+ vibe: 'bg-red-100 text-red-700 border-red-400' // Mistral Vibe brand orange-red (#FA500F)
145
+ };
146
+ //# sourceMappingURL=modelDefinitions.js.map
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Default high-level review guidance for the `/review` command.
3
+ *
4
+ * This is the single source of truth for the *overridable* portion of the
5
+ * review prompt — the part the operator-configurable `pr_review_prompt` setting
6
+ * replaces. It is consumed in two places:
7
+ * - the review prompt builder (`buildReviewPrompt`) uses it at review time
8
+ * whenever no override has been configured, and
9
+ * - the Settings UI prefills the `pr_review_prompt` field with it so operators
10
+ * can see exactly what the override replaces before editing it.
11
+ *
12
+ * The mandatory structured output sections (Overall Evaluation, Findings, and
13
+ * the final `Score: N/10` line) are NOT part of this guidance — they are always
14
+ * appended by the builder regardless of any override, because the /fix gatherer
15
+ * and ultrafix score extraction depend on that exact format.
16
+ */
17
+ export const DEFAULT_REVIEW_GUIDANCE = `Perform a thorough code review of this pull request based on the CURRENT diff. Your response MUST contain exactly the following three sections with the headers shown below. Do not omit any section.`;
18
+ //# sourceMappingURL=reviewPrompt.js.map
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Usage configuration and metrics types for agent resource management.
3
+ *
4
+ * AgentTankConfig defines the allowance/quota settings for an agent,
5
+ * supporting subscription billing models where each agent has a "tank"
6
+ * of available usage.
7
+ *
8
+ * UsageMetrics captures pre-call, post-call, and delta values to track
9
+ * how much allowance each LLM call consumed. Supports nested generic
10
+ * properties since providers have varying usage structures.
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=usageTypes.js.map
@@ -0,0 +1,30 @@
1
+ /**
2
+ * GitHub user whitelist — single source of truth.
3
+ *
4
+ * Consumed by the API access gate, the daemon trigger-authorization gate,
5
+ * and the PR-comment command gate. One allowlist (GITHUB_USER_WHITELIST)
6
+ * governs every surface.
7
+ *
8
+ * An empty/unset whitelist means open access. Matching is case-insensitive.
9
+ * Bot accounts (trailing "[bot]") require an explicit `name[bot]` entry —
10
+ * a plain `name` entry does NOT match `name[bot]`, preventing a GitHub App
11
+ * whose slug matches a whitelisted username from passing the gate.
12
+ */
13
+ export function getGithubUserWhitelist() {
14
+ return (process.env.GITHUB_USER_WHITELIST ?? '')
15
+ .split(',')
16
+ .map((entry) => entry.trim())
17
+ .filter((entry) => entry.length > 0);
18
+ }
19
+ export function isGithubUserWhitelisted(login) {
20
+ const whitelist = getGithubUserWhitelist();
21
+ if (whitelist.length === 0) {
22
+ return true;
23
+ }
24
+ if (!login) {
25
+ return false;
26
+ }
27
+ const lower = login.toLowerCase();
28
+ return whitelist.some((entry) => entry.toLowerCase() === lower);
29
+ }
30
+ //# sourceMappingURL=userWhitelist.js.map
@@ -0,0 +1,21 @@
1
+ // URL.hostname returns brackets for IPv6, e.g. '[::1]'.
2
+ const LOCALHOST_HOSTS = ['localhost', '127.0.0.1', '[::1]'];
3
+ /**
4
+ * Validate a relay URL: must be parseable and use https (http allowed for localhost).
5
+ * Returns an error message string, or `null` when valid.
6
+ */
7
+ export function validateRelayUrl(url) {
8
+ let parsed;
9
+ try {
10
+ parsed = new URL(url);
11
+ }
12
+ catch {
13
+ return `Relay URL ("${url}") is not a valid URL`;
14
+ }
15
+ const isLocalhost = LOCALHOST_HOSTS.includes(parsed.hostname);
16
+ if (parsed.protocol !== 'https:' && !(parsed.protocol === 'http:' && isLocalhost)) {
17
+ return 'Relay URL must use https:// (http is only allowed for localhost)';
18
+ }
19
+ return null;
20
+ }
21
+ //# sourceMappingURL=validateRelayUrl.js.map
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "propr-cli",
3
+ "version": "0.8.3",
4
+ "description": "CLI for interacting with the ProPR backend",
5
+ "type": "module",
6
+ "bin": {
7
+ "propr": "./dist/index.js"
8
+ },
9
+ "main": "dist/index.js",
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "engines": {
14
+ "node": ">=22"
15
+ },
16
+ "dependencies": {
17
+ "commander": "^13.1.0",
18
+ "dotenv": "^16.5.0",
19
+ "ink": "^7.0.5",
20
+ "react": "^19.2.7"
21
+ },
22
+ "keywords": [
23
+ "propr",
24
+ "cli",
25
+ "github",
26
+ "ai",
27
+ "code-review",
28
+ "automation"
29
+ ],
30
+ "license": "ISC"
31
+ }