context-foundry 2.5.3 → 2.5.4

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.
package/Dockerfile ADDED
@@ -0,0 +1,17 @@
1
+ # Context Foundry Dashboard (Web UI only)
2
+ # The daemon runs on the host - this just serves the monitoring UI
3
+ FROM nginx:alpine
4
+
5
+ # Copy dashboard HTML
6
+ COPY cf.html /usr/share/nginx/html/index.html
7
+ COPY cf.html /usr/share/nginx/html/cf.html
8
+
9
+ # Copy nginx config
10
+ COPY nginx.conf /etc/nginx/conf.d/default.conf
11
+
12
+ # Expose dashboard port
13
+ EXPOSE 8421
14
+
15
+ # Health check
16
+ HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
17
+ CMD wget -q --spider http://localhost:8421/ || exit 1
package/bin/cfd.js CHANGED
@@ -3,7 +3,9 @@
3
3
  /**
4
4
  * Context Foundry Daemon CLI - npm wrapper for Python engine
5
5
  *
6
- * This is a thin shim that delegates to the Python `cfd` command.
6
+ * This shim delegates to the Python CLI via `python3 -m context_foundry.daemon.cli`.
7
+ * We invoke the module directly to avoid PATH conflicts (the npm-installed `cfd`
8
+ * command would otherwise find itself via `which cfd`, causing infinite recursion).
7
9
  */
8
10
 
9
11
  const { spawn, spawnSync } = require('child_process');
@@ -27,9 +29,9 @@ function log(msg, color = '') {
27
29
  }
28
30
 
29
31
  /**
30
- * Check if Python 3.10+ is available
32
+ * Find Python 3.10+ command
31
33
  */
32
- function checkPython() {
34
+ function findPython() {
33
35
  const pythonCommands = ['python3', 'python'];
34
36
 
35
37
  for (const cmd of pythonCommands) {
@@ -54,48 +56,65 @@ function checkPython() {
54
56
  }
55
57
 
56
58
  /**
57
- * Get the path to cfd from the Python package
59
+ * Check if context-foundry Python package is installed
58
60
  */
59
- function getCfdPath() {
60
- // First try: check if cfd is in PATH
61
- const which = spawnSync('which', ['cfd'], { encoding: 'utf-8' });
62
- if (which.status === 0) {
63
- return 'cfd';
64
- }
61
+ function checkPythonPackage(pythonCmd) {
62
+ const result = spawnSync(pythonCmd, ['-c', 'import context_foundry.daemon.cli'], {
63
+ encoding: 'utf-8',
64
+ stdio: ['pipe', 'pipe', 'pipe']
65
+ });
66
+ return result.status === 0;
67
+ }
65
68
 
66
- // Second try: use the tools/cfd script directly if we're in the repo
67
- const localCfd = require('path').join(__dirname, '../../tools/cfd');
68
- try {
69
- require('fs').accessSync(localCfd, require('fs').constants.X_OK);
70
- return localCfd;
71
- } catch (e) {
72
- // Not in repo or not executable
69
+ /**
70
+ * Install context-foundry via pipx (preferred) or pip with --user
71
+ */
72
+ function installPackage(pythonCmd) {
73
+ // Try pipx first (best for CLI tools on macOS/Linux)
74
+ const pipxCheck = spawnSync('which', ['pipx'], { encoding: 'utf-8' });
75
+ if (pipxCheck.status === 0) {
76
+ log(`${colors.yellow}Installing context-foundry via pipx...${colors.reset}`);
77
+ const pipx = spawnSync('pipx', ['install', 'context-foundry'], {
78
+ stdio: 'inherit'
79
+ });
80
+ if (pipx.status === 0) return true;
81
+ // If pipx fails (already installed, etc), try reinstall
82
+ const pipxReinstall = spawnSync('pipx', ['reinstall', 'context-foundry'], {
83
+ stdio: 'inherit'
84
+ });
85
+ if (pipxReinstall.status === 0) return true;
73
86
  }
74
87
 
75
- return null;
88
+ // Fallback: pip with --user flag (avoids PEP 668 errors)
89
+ log(`${colors.yellow}Installing context-foundry via pip --user...${colors.reset}`);
90
+ const pip = spawnSync(pythonCmd, ['-m', 'pip', 'install', '--user', 'context-foundry'], {
91
+ stdio: 'inherit'
92
+ });
93
+ if (pip.status === 0) return true;
94
+
95
+ // Last resort: suggest pipx installation
96
+ log(`\n${colors.yellow}Tip: Install pipx for better Python CLI tool management:${colors.reset}`);
97
+ log(` ${colors.cyan}brew install pipx && pipx ensurepath${colors.reset}`);
98
+ return false;
76
99
  }
77
100
 
78
101
  /**
79
- * Run the Python cfd command with all arguments passed through
102
+ * Run the Python CLI module with all arguments
80
103
  */
81
- function runCfd(cfdPath, args) {
82
- const cfd = spawn(cfdPath, args, {
104
+ function runPythonCli(pythonCmd, args) {
105
+ // Call the Python module directly - this avoids PATH issues entirely
106
+ const proc = spawn(pythonCmd, ['-m', 'context_foundry.daemon.cli', ...args], {
83
107
  stdio: 'inherit',
84
108
  env: process.env
85
109
  });
86
110
 
87
- cfd.on('error', (err) => {
88
- if (err.code === 'ENOENT') {
89
- error('The `cfd` command is not found.');
90
- log('\nTry running:', colors.cyan);
91
- log(' pip install context-foundry', colors.bold);
92
- process.exit(1);
93
- }
94
- throw err;
111
+ proc.on('error', (err) => {
112
+ error(`Failed to start Python: ${err.message}`);
113
+ process.exit(1);
95
114
  });
96
115
 
97
- cfd.on('close', (code) => {
98
- process.exit(code);
116
+ proc.on('close', (code) => {
117
+ process.exit(code || 0);
99
118
  });
100
119
  }
101
120
 
@@ -121,33 +140,31 @@ ${colors.yellow}More Info:${colors.reset}
121
140
  function main() {
122
141
  const args = process.argv.slice(2);
123
142
 
124
- // Check Python availability
125
- const python = checkPython();
143
+ // Find Python 3.10+
144
+ const python = findPython();
126
145
  if (!python) {
127
146
  error('Python 3.10+ is required but not found.');
147
+ log('\nPlease install Python 3.10 or later:', colors.yellow);
148
+ log(' brew install python@3.12', colors.cyan);
128
149
  process.exit(1);
129
150
  }
130
151
 
131
- // Find cfd command
132
- const cfdPath = getCfdPath();
133
- if (!cfdPath) {
134
- log(`${colors.yellow}The 'cfd' command is not installed.${colors.reset}`);
135
- log(`Installing context-foundry via pip...`);
136
-
137
- const pip = spawnSync(python.cmd, ['-m', 'pip', 'install', 'context-foundry'], {
138
- stdio: 'inherit'
139
- });
152
+ // Check if context-foundry is installed
153
+ if (!checkPythonPackage(python.cmd)) {
154
+ log(`${colors.yellow}context-foundry Python package not found.${colors.reset}`);
140
155
 
141
- if (pip.status !== 0) {
156
+ if (!installPackage(python.cmd)) {
142
157
  error('Failed to install context-foundry via pip.');
158
+ log('\nTry manually:', colors.yellow);
159
+ log(' pip install context-foundry', colors.cyan);
143
160
  process.exit(1);
144
161
  }
145
162
 
146
163
  log(`${colors.green}Successfully installed!${colors.reset}\n`);
147
164
  }
148
165
 
149
- // Run cfd with all arguments
150
- runCfd(cfdPath || 'cfd', args);
166
+ // Run the Python CLI
167
+ runPythonCli(python.cmd, args);
151
168
  }
152
169
 
153
170
  main();