create-walle 0.2.1 → 0.3.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.
@@ -81,7 +81,8 @@ function install(targetDir) {
81
81
  const ownerName = detectName().replace(/[\r\n=]/g, '').trim().slice(0, 200);
82
82
  const timezone = detectTimezone();
83
83
  const nameParts = ownerName.split(/\s+/);
84
- const port = process.env.WALLE_PORT || '4567';
84
+ const port = process.env.CTM_PORT || '3456';
85
+ const wallePort = String(parseInt(port) + 1);
85
86
 
86
87
  console.log(` ${DIM}Owner: ${ownerName}${RESET}`);
87
88
  console.log(` ${DIM}Timezone: ${timezone}${RESET}`);
@@ -110,6 +111,7 @@ function install(targetDir) {
110
111
  '# ANTHROPIC_API_KEY=sk-ant-...',
111
112
  '',
112
113
  `CTM_PORT=${port}`,
114
+ `WALL_E_PORT=${wallePort}`,
113
115
  '',
114
116
  '# SLACK_TOKEN=',
115
117
  '# SLACK_OWNER_USER_ID=',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-walle",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Set up Wall-E — your personal digital twin",
5
5
  "bin": {
6
6
  "create-walle": "bin/create-walle.js"
@@ -3792,6 +3792,7 @@ function startRenameReviewTitle(titleEl) {
3792
3792
  titleEl.textContent = newName;
3793
3793
  renderFilteredSessions();
3794
3794
  renderSessionList();
3795
+ renderTabs();
3795
3796
  } else {
3796
3797
  titleEl.textContent = currentText;
3797
3798
  }
@@ -3836,6 +3837,7 @@ function startRenameRecentSession(sessionId, spanEl) {
3836
3837
  }
3837
3838
  renderFilteredSessions();
3838
3839
  renderSessionList();
3840
+ renderTabs();
3839
3841
  }
3840
3842
 
3841
3843
  input.addEventListener('blur', finish);
@@ -197,11 +197,27 @@
197
197
  btn.textContent = 'Connecting...';
198
198
  const r = await fetch('/api/wall-e/slack/auth', { method: 'POST' });
199
199
  const d = await r.json();
200
- if (d.url) {
201
- window.open(d.url, '_blank');
202
- btn.textContent = 'Check browser...';
203
- } else if (d.ok) {
200
+ if (d.ok && d.already) {
204
201
  btn.outerHTML = '<span class="badge badge-connected">Connected</span>';
202
+ } else if (d.ok) {
203
+ btn.textContent = 'Check browser...';
204
+ // Poll for completion (OAuth callback happens server-side)
205
+ let attempts = 0;
206
+ const poll = setInterval(async () => {
207
+ attempts++;
208
+ try {
209
+ const sr = await fetch('/api/setup/status');
210
+ const sd = await sr.json();
211
+ if (sd.slack_connected) {
212
+ clearInterval(poll);
213
+ btn.outerHTML = '<span class="badge badge-connected">Connected</span>';
214
+ } else if (attempts > 60) {
215
+ clearInterval(poll);
216
+ btn.textContent = 'Timed out';
217
+ btn.disabled = false;
218
+ }
219
+ } catch {}
220
+ }, 2000);
205
221
  } else {
206
222
  btn.textContent = d.error || 'Failed';
207
223
  btn.disabled = false;
@@ -21,7 +21,7 @@ const approvalAgent = require('./approval-agent');
21
21
  const { handleReviewApi, checkForChanges } = require('./api-reviews');
22
22
  const { sessions } = require('./server-state');
23
23
 
24
- // WALL-E API now served directly by the WALL-E process (port 3457)
24
+ // WALL-E API served directly by the WALL-E process (default: CTM_PORT + 1)
25
25
  // Frontend connects to it via CORS. Keep proxy as fallback for environments where WALL-E isn't running separately.
26
26
  let handleWalleApi;
27
27
  try { handleWalleApi = require('../wall-e/api-walle').handleWalleApi; } catch {}
@@ -30,6 +30,7 @@ try { handleWalleApi = require('../wall-e/api-walle').handleWalleApi; } catch {}
30
30
  const CONFIG_DIR = process.env.CTM_DATA_DIR || path.join(process.env.HOME, '.walle', 'data');
31
31
  const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
32
32
  const PORT = parseInt(process.env.CTM_PORT || '3456', 10);
33
+ const WALLE_PORT = parseInt(process.env.WALL_E_PORT || String(PORT + 1), 10);
33
34
  const HOST = process.env.CTM_HOST || '127.0.0.1';
34
35
 
35
36
  function loadConfig() {
@@ -2096,8 +2097,7 @@ const _ctmStartTime = Date.now();
2096
2097
 
2097
2098
  function apiServicesStatus(req, res) {
2098
2099
  const ctmUptime = Math.floor((Date.now() - _ctmStartTime) / 1000);
2099
- // Check Wall-E on port 3457
2100
- execFile('lsof', ['-ti', ':3457'], (err, stdout) => {
2100
+ execFile('lsof', ['-ti', ':' + WALLE_PORT], (err, stdout) => {
2101
2101
  const pids = (stdout || '').trim().split('\n').filter(Boolean);
2102
2102
  // Filter to only node processes
2103
2103
  let wallePid = null;
@@ -2114,7 +2114,7 @@ function apiServicesStatus(req, res) {
2114
2114
  }
2115
2115
 
2116
2116
  function apiStopWalle(req, res) {
2117
- execFile('lsof', ['-ti', ':3457'], (err, stdout) => {
2117
+ execFile('lsof', ['-ti', ':' + WALLE_PORT], (err, stdout) => {
2118
2118
  const pids = (stdout || '').trim().split('\n').filter(Boolean);
2119
2119
  if (pids.length === 0) {
2120
2120
  res.writeHead(200, { 'Content-Type': 'application/json' });
@@ -2133,7 +2133,7 @@ function apiStartWalle(req, res) {
2133
2133
  const walleDir = path.join(__dirname, '..', 'wall-e');
2134
2134
  const agentScript = path.join(walleDir, 'agent.js');
2135
2135
  // Check if already running
2136
- execFile('lsof', ['-ti', ':3457'], (err, stdout) => {
2136
+ execFile('lsof', ['-ti', ':' + WALLE_PORT], (err, stdout) => {
2137
2137
  const pids = (stdout || '').trim().split('\n').filter(Boolean);
2138
2138
  if (pids.length > 0) {
2139
2139
  res.writeHead(200, { 'Content-Type': 'application/json' });
@@ -2143,7 +2143,7 @@ function apiStartWalle(req, res) {
2143
2143
  const child = require('child_process').spawn(
2144
2144
  process.execPath,
2145
2145
  [agentScript],
2146
- { cwd: walleDir, detached: true, stdio: 'ignore', env: { ...process.env } }
2146
+ { cwd: walleDir, detached: true, stdio: 'ignore', env: { ...process.env, WALL_E_PORT: String(WALLE_PORT) } }
2147
2147
  );
2148
2148
  child.unref();
2149
2149
  res.writeHead(200, { 'Content-Type': 'application/json' });
@@ -2181,8 +2181,8 @@ function apiRestartWalle(req, res) {
2181
2181
  const walleDir = path.join(__dirname, '..', 'wall-e');
2182
2182
  const agentScript = path.join(walleDir, 'agent.js');
2183
2183
 
2184
- // Kill existing Wall-E process on port 3457
2185
- execFile('lsof', ['-ti', ':3457'], (err, stdout) => {
2184
+ // Kill existing Wall-E process
2185
+ execFile('lsof', ['-ti', ':' + WALLE_PORT], (err, stdout) => {
2186
2186
  const pids = (stdout || '').trim().split('\n').filter(Boolean);
2187
2187
  for (const pid of pids) {
2188
2188
  try { process.kill(parseInt(pid), 'SIGTERM'); } catch {}
@@ -2193,7 +2193,7 @@ function apiRestartWalle(req, res) {
2193
2193
  const child = require('child_process').spawn(
2194
2194
  process.execPath,
2195
2195
  [agentScript],
2196
- { cwd: walleDir, detached: true, stdio: 'ignore', env: { ...process.env } }
2196
+ { cwd: walleDir, detached: true, stdio: 'ignore', env: { ...process.env, WALL_E_PORT: String(WALLE_PORT) } }
2197
2197
  );
2198
2198
  child.unref();
2199
2199
  res.writeHead(200, { 'Content-Type': 'application/json' });
@@ -208,12 +208,19 @@ function handleWalleApi(req, res, url) {
208
208
  if (p === '/api/wall-e/slack/auth' && m === 'POST') {
209
209
  try {
210
210
  const slackMcp = require('./tools/slack-mcp');
211
+ // If already authenticated, return immediately
212
+ if (slackMcp.isAuthenticated()) {
213
+ jsonResponse(res, { ok: true, already: true });
214
+ return true;
215
+ }
216
+ // Start OAuth — browser opens server-side, resolve on callback
211
217
  slackMcp.authenticate().then(token => {
212
218
  console.log('[wall-e] Slack OAuth completed');
213
219
  }).catch(err => {
214
220
  console.error('[wall-e] Slack OAuth failed:', err.message);
215
221
  });
216
- jsonResponse(res, { data: { message: 'OAuth flow started — check your browser' } });
222
+ // Tell client the flow started (browser will open)
223
+ jsonResponse(res, { ok: true, pending: true });
217
224
  } catch (e) {
218
225
  jsonResponse(res, { error: e.message }, 500);
219
226
  }