@latentforce/shift 1.0.8 → 1.0.9

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/README.md CHANGED
@@ -10,15 +10,31 @@ npm install -g @latentforce/shift
10
10
 
11
11
  ## Quick Start
12
12
 
13
- ### 1. Initialize your project
13
+ ### Guest mode (zero-config)
14
14
 
15
15
  ```bash
16
16
  cd /path/to/your/project
17
- shift-cli start # Configure API key and project
17
+ shift-cli init --guest # Auto-creates guest key + project, scans, and indexes
18
+ ```
19
+
20
+ ### With an API key
21
+
22
+ ```bash
23
+ # Create a new project and index it (prompts for template selection)
24
+ shift-cli init --api-key YOUR_KEY --project-name "My App"
25
+
26
+ # Fully non-interactive (CI/CD friendly)
27
+ shift-cli init --api-key YOUR_KEY --project-name "My App" --template TEMPLATE_ID
28
+ ```
29
+
30
+ ### Interactive (original behavior)
31
+
32
+ ```bash
33
+ shift-cli start # Configure API key and project interactively
18
34
  shift-cli init # Index project files
19
35
  ```
20
36
 
21
- ### 2. Add to Claude Code
37
+ ### Add to Claude Code
22
38
 
23
39
  ```bash
24
40
  claude mcp add-json shift '{"type":"stdio","command":"shift-cli","args":["mcp"],"env":{"SHIFT_PROJECT_ID":"YOUR_PROJECT_ID"}}'
@@ -30,7 +46,7 @@ Or using npx:
30
46
  claude mcp add-json shift '{"type":"stdio","command":"npx","args":["@latentforce/shift","mcp"],"env":{"SHIFT_PROJECT_ID":"YOUR_PROJECT_ID"}}'
31
47
  ```
32
48
 
33
- ### 3. Add to Claude Desktop
49
+ ### Add to Claude Desktop
34
50
 
35
51
  Add to your config file (`%APPDATA%\Claude\claude_desktop_config.json` on Windows, `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
36
52
 
@@ -48,39 +64,67 @@ Add to your config file (`%APPDATA%\Claude\claude_desktop_config.json` on Window
48
64
  }
49
65
  ```
50
66
 
51
- ## MCP Tools
52
-
53
- | Tool | Description |
54
- |------|-------------|
55
- | `blast_radius` | Analyze what would be affected if a file is modified |
56
- | `dependencies` | Get all dependencies for a file |
57
- | `file_summary` | Generate a summary of a file |
58
-
59
67
  ## CLI Commands
60
68
 
61
69
  | Command | Description |
62
70
  |---------|-------------|
63
71
  | `shift-cli start` | Start daemon and configure project |
64
- | `shift-cli init` | Index project files |
72
+ | `shift-cli init` | Scan and index project files |
73
+ | `shift-cli update-drg` | Update the dependency relationship graph |
65
74
  | `shift-cli stop` | Stop the daemon |
66
75
  | `shift-cli status` | Show current status |
67
76
  | `shift-cli config` | Manage configuration |
68
77
 
69
- ## Custom Backend URLs
78
+ ### CLI Flags
79
+
80
+ #### `shift-cli init`
81
+
82
+ | Flag | Description |
83
+ |------|-------------|
84
+ | `--guest` | Use guest authentication (auto-creates project) |
85
+ | `--api-key <key>` | Provide API key directly |
86
+ | `--project-name <name>` | Create new project or match existing by name |
87
+ | `--project-id <id>` | Use existing project UUID |
88
+ | `--template <id>` | Migration template ID for project creation |
89
+ | `-f, --force` | Force re-indexing even if already indexed |
70
90
 
71
- **CLI** (set once globally):
91
+ #### `shift-cli start`
92
+
93
+ | Flag | Description |
94
+ |------|-------------|
95
+ | `--guest` | Use guest authentication (auto-creates project) |
96
+ | `--api-key <key>` | Provide API key directly |
97
+ | `--project-name <name>` | Create new project or match existing by name |
98
+ | `--project-id <id>` | Use existing project UUID |
99
+ | `--template <id>` | Migration template ID for project creation |
100
+
101
+ #### `shift-cli update-drg`
102
+
103
+ | Flag | Description |
104
+ |------|-------------|
105
+ | `-m, --mode <mode>` | `baseline` (all files) or `incremental` (git-changed only, default) |
106
+
107
+ ### Update DRG
108
+
109
+ After initializing your project, update the dependency graph to keep code intelligence in sync:
72
110
 
73
111
  ```bash
74
- shift-cli config set api-url https://your-api.example.com
75
- shift-cli config set orch-url https://your-orch.example.com
76
- shift-cli config set ws-url wss://your-orch.example.com
112
+ shift-cli update-drg # Incremental (default) — only git-changed files
113
+ shift-cli update-drg --mode baseline # Full re-scan of all JS/TS files
77
114
  ```
78
115
 
79
- **MCP Server** (add to env in Claude config):
116
+ Scans `.js`, `.jsx`, `.ts`, `.tsx`, `.mjs`, `.cjs` files.
80
117
 
81
- ```json
82
- "env": {
83
- "SHIFT_PROJECT_ID": "YOUR_PROJECT_ID",
84
- "SHIFT_BACKEND_URL": "https://your-api.example.com"
85
- }
86
- ```
118
+ ## MCP Tools
119
+
120
+ | Tool | Description |
121
+ |------|-------------|
122
+ | `blast_radius` | Analyze what files would be affected if a file is modified or deleted |
123
+ | `dependencies` | Get all dependencies for a file with relationship summaries |
124
+ | `file_summary` | Get a summary of a file with optional parent directory context |
125
+
126
+ Each tool accepts an optional `project_id` parameter. If not provided, it falls back to the `SHIFT_PROJECT_ID` environment variable.
127
+
128
+ MCP tools return formatted markdown and include:
129
+ - **Path normalization** — backslashes, leading `./` and `/` are handled automatically
130
+ - **Actionable error messages** — missing graph prompts you to run `update-drg`, missing files explain possible causes
@@ -1,12 +1,14 @@
1
1
  import { exec } from 'child_process';
2
2
  import { promisify } from 'util';
3
3
  import { createInterface } from 'readline';
4
- import { getApiKey, setApiKey, setGuestKey, isGuestKey, readProjectConfig, writeProjectConfig } from '../../utils/config.js';
5
- import { promptApiKey, promptKeyChoice } from '../../utils/prompts.js';
6
- import { requestGuestKey, fetchProjectStatus } from '../../utils/api-client.js';
7
- import { getDaemonStatus } from '../../daemon/daemon-manager.js';
4
+ import { createRequire } from 'module';
5
+ import { readProjectConfig, writeProjectConfig } from '../../utils/config.js';
6
+ import { fetchProjectStatus, sendInitScan } from '../../utils/api-client.js';
7
+ import { resolveApiKey, resolveProject } from '../../utils/auth-resolver.js';
8
+ import { getDaemonStatus, startDaemon } from '../../daemon/daemon-manager.js';
8
9
  import { getProjectTree, extractAllFilePaths, categorizeFiles } from '../../utils/tree-scanner.js';
9
- import { sendInitScan } from '../../utils/api-client.js';
10
+ const require = createRequire(import.meta.url);
11
+ const { version } = require('../../../package.json');
10
12
  const execAsync = promisify(exec);
11
13
  /**
12
14
  * Prompt user to confirm re-indexing an already indexed project
@@ -25,64 +27,64 @@ async function promptForReindex() {
25
27
  }
26
28
  export async function initCommand(options = {}) {
27
29
  const projectRoot = process.cwd();
30
+ const isAuthInteractive = !options.guest && !options.apiKey;
31
+ const isProjectInteractive = !!(process.stdin.isTTY);
28
32
  console.log('╔═══════════════════════════════════════════════╗');
29
33
  console.log('║ Initializing Shift Project ║');
30
34
  console.log('╚═══════════════════════════════════════════════╝\n');
31
- // Step 1: Check API key (with guest flow support)
35
+ // Step 1: Resolve API key
32
36
  console.log('[Init] Step 1/5: Checking API key...');
33
- let apiKey = getApiKey();
34
- if (!apiKey) {
35
- const choice = await promptKeyChoice();
36
- if (choice === 'paid') {
37
- apiKey = await promptApiKey();
38
- setApiKey(apiKey);
39
- console.log('[Init] API key saved to ~/.shift/config.json\n');
40
- }
41
- else {
42
- console.log('\n[Init] Requesting guest session...');
43
- try {
44
- const guestResponse = await requestGuestKey();
45
- setGuestKey(guestResponse.api_key);
46
- apiKey = guestResponse.api_key;
47
- console.log('[Init] ✓ Guest session started\n');
48
- }
49
- catch (error) {
50
- console.error(`\n❌ Failed to get guest key: ${error.message}`);
51
- process.exit(1);
52
- }
53
- }
54
- }
55
- else if (isGuestKey()) {
56
- console.log('[Init] ✓ Guest key found\n');
57
- }
58
- else {
59
- console.log('[Init] ✓ API key found\n');
60
- }
61
- // Step 2: Check project config
37
+ const authResult = await resolveApiKey({
38
+ guest: options.guest,
39
+ apiKey: options.apiKey,
40
+ interactive: isAuthInteractive,
41
+ commandLabel: 'Init',
42
+ });
43
+ const apiKey = authResult.apiKey;
44
+ // Step 2: Resolve project
62
45
  console.log('[Init] Step 2/5: Checking project configuration...');
46
+ // If guest flow returned a project_id, save it before resolving
47
+ if (authResult.projectId && !readProjectConfig(projectRoot)) {
48
+ const { setProject } = await import('../../utils/config.js');
49
+ setProject(authResult.projectId, options.projectName || 'Guest Project', projectRoot);
50
+ }
51
+ const project = await resolveProject({
52
+ apiKey,
53
+ projectId: options.projectId,
54
+ projectName: options.projectName,
55
+ template: options.template,
56
+ interactive: isProjectInteractive,
57
+ commandLabel: 'Init',
58
+ projectRoot,
59
+ });
60
+ // Re-read project config (may have been written by resolveProject)
63
61
  const projectConfig = readProjectConfig(projectRoot);
64
62
  if (!projectConfig) {
65
- console.error('\n❌ No project configured for this directory.');
66
- console.log('Run "shift start" first to configure the project.\n');
63
+ console.error('\n❌ Failed to configure project.');
67
64
  process.exit(1);
68
65
  }
69
- console.log(`[Init] ✓ Project: ${projectConfig.project_name} (${projectConfig.project_id})\n`);
70
66
  // Check if project is already indexed (skip check if --force flag is used)
71
67
  if (!options.force) {
72
68
  try {
73
- const projectStatus = await fetchProjectStatus(apiKey, projectConfig.project_id);
69
+ const projectStatus = await fetchProjectStatus(apiKey, project.projectId);
74
70
  if (projectStatus.indexed) {
75
71
  console.log(`[Init] ✓ Project already indexed (${projectStatus.file_count} files)\n`);
76
- const shouldReindex = await promptForReindex();
77
- if (!shouldReindex) {
78
- console.log('\n╔═══════════════════════════════════════════════╗');
79
- console.log('║ Project Already Initialized ║');
80
- console.log('╚═══════════════════════════════════════════════╝');
81
- console.log('\nUse "shift status" to check the current status.');
82
- console.log('Use "shift init --force" to force re-indexing.\n');
72
+ if (isProjectInteractive) {
73
+ const shouldReindex = await promptForReindex();
74
+ if (!shouldReindex) {
75
+ console.log('\n╔═══════════════════════════════════════════════╗');
76
+ console.log('║ Project Already Initialized ║');
77
+ console.log('╚═══════════════════════════════════════════════╝');
78
+ console.log('\nUse "shift-cli status" to check the current status.');
79
+ console.log('Use "shift-cli init --force" to force re-indexing.\n');
80
+ return;
81
+ }
82
+ console.log('\n[Init] Proceeding with re-indexing...\n');
83
+ }
84
+ else {
85
+ console.log('[Init] Already indexed. Use --force to re-index.\n');
83
86
  return;
84
87
  }
85
- console.log('\n[Init] Proceeding with re-indexing...\n');
86
88
  }
87
89
  }
88
90
  catch {
@@ -93,14 +95,28 @@ export async function initCommand(options = {}) {
93
95
  else {
94
96
  console.log('[Init] Force flag detected, skipping indexing status check...\n');
95
97
  }
96
- // Step 3: Check daemon status (warn if not running)
98
+ // Step 3: Check daemon status start it automatically if not running
97
99
  console.log('[Init] Step 3/5: Checking daemon status...');
98
- const status = getDaemonStatus(projectRoot);
99
- if (!status.running) {
100
- console.log('[Init] ⚠️ Warning: Daemon is not running. Run "shift start" to start it.\n');
100
+ const daemonStatus = getDaemonStatus(projectRoot);
101
+ if (!daemonStatus.running) {
102
+ console.log('[Init] Daemon not running. Starting it...');
103
+ try {
104
+ const daemonResult = await startDaemon(projectRoot, project.projectId, apiKey);
105
+ if (daemonResult.success) {
106
+ console.log(`[Init] ✓ Daemon started (PID: ${daemonResult.pid})\n`);
107
+ }
108
+ else {
109
+ console.log(`[Init] ⚠️ Could not start daemon: ${daemonResult.error}`);
110
+ console.log('[Init] Continuing without daemon — run "shift-cli start" later.\n');
111
+ }
112
+ }
113
+ catch (err) {
114
+ console.log(`[Init] ⚠️ Could not start daemon: ${err.message}`);
115
+ console.log('[Init] Continuing without daemon — run "shift-cli start" later.\n');
116
+ }
101
117
  }
102
118
  else {
103
- console.log(`[Init] ✓ Daemon running (PID: ${status.pid}, Connected: ${status.connected})\n`);
119
+ console.log(`[Init] ✓ Daemon running (PID: ${daemonStatus.pid}, Connected: ${daemonStatus.connected})\n`);
104
120
  }
105
121
  // Step 4: Scan project structure (matching extension's Step 6)
106
122
  console.log('[Init] Step 4/5: Scanning project structure...');
@@ -150,7 +166,7 @@ export async function initCommand(options = {}) {
150
166
  // Step 5: Send scan to backend (matching extension's Step 9)
151
167
  console.log('[Init] Step 5/5: Sending scan to backend...');
152
168
  const payload = {
153
- project_id: projectConfig.project_id,
169
+ project_id: project.projectId,
154
170
  project_tree: treeData,
155
171
  git_info: gitInfo,
156
172
  file_manifest: {
@@ -158,13 +174,13 @@ export async function initCommand(options = {}) {
158
174
  categorized: categorized,
159
175
  },
160
176
  metadata: {
161
- extension_version: '1.0.2-cli', // CLI version
177
+ extension_version: `${version}-cli`,
162
178
  scan_timestamp: new Date().toISOString(),
163
- project_name: projectConfig.project_name,
179
+ project_name: project.projectName,
164
180
  },
165
181
  };
166
182
  try {
167
- const response = await sendInitScan(apiKey, projectConfig.project_id, payload);
183
+ const response = await sendInitScan(apiKey, project.projectId, payload);
168
184
  console.log('[Init] ✓ Backend initialization completed');
169
185
  console.log(`[Init] Files read: ${response.files_read}`);
170
186
  console.log(`[Init] Files failed: ${response.files_failed}`);
@@ -181,15 +197,17 @@ export async function initCommand(options = {}) {
181
197
  writeProjectConfig(projectConfig, projectRoot);
182
198
  console.log(`[Init] ✓ Agent info saved: ${agentInfo.agent_id}`);
183
199
  }
200
+ if (response.files_read === 0 && response.files_failed > 0) {
201
+ console.log(`\n[Init] ⚠️ No files were read (${response.files_failed} failed).`);
202
+ }
184
203
  console.log('\n╔═══════════════════════════════════════════════╗');
185
204
  console.log('║ ✓ Project Initialization Complete ║');
186
205
  console.log('╚═══════════════════════════════════════════════╝');
206
+ console.log('\nIndexing is running in the background. Use "shift-cli status" to check progress.');
187
207
  if (response.next_steps) {
188
208
  console.log('\nNext steps:');
189
209
  response.next_steps.forEach((step) => console.log(` - ${step}`));
190
210
  }
191
- console.log('\nFile indexing has been triggered. This may take a few moments.');
192
- console.log('Use "shift status" to check the daemon connection.\n');
193
211
  }
194
212
  catch (error) {
195
213
  console.error(`\n❌ Failed to initialize project: ${error.message}`);
@@ -1,75 +1,38 @@
1
- import { getApiKey, setApiKey, setGuestKey, isGuestKey, setProject, readProjectConfig } from '../../utils/config.js';
2
- import { promptApiKey, promptProjectId, promptSelectProject, promptKeyChoice } from '../../utils/prompts.js';
1
+ import { readProjectConfig, setProject } from '../../utils/config.js';
3
2
  import { startDaemon, getDaemonStatus } from '../../daemon/daemon-manager.js';
4
- import { fetchProjects, requestGuestKey } from '../../utils/api-client.js';
5
- export async function startCommand() {
3
+ import { resolveApiKey, resolveProject } from '../../utils/auth-resolver.js';
4
+ export async function startCommand(options = {}) {
6
5
  const projectRoot = process.cwd();
6
+ const isAuthInteractive = !options.guest && !options.apiKey;
7
+ const isProjectInteractive = !!(process.stdin.isTTY);
7
8
  console.log('╔════════════════════════════════════════════╗');
8
9
  console.log('║ Starting Shift ║');
9
10
  console.log('╚════════════════════════════════════════════╝\n');
10
- // Step 1: Ensure API key exists
11
+ // Step 1: Resolve API key
11
12
  console.log('[Start] Step 1/4: Checking API key...');
12
- let apiKey = getApiKey();
13
- if (!apiKey) {
14
- const choice = await promptKeyChoice();
15
- if (choice === 'paid') {
16
- apiKey = await promptApiKey();
17
- setApiKey(apiKey);
18
- console.log('[Start] API key saved to ~/.shift/config.json\n');
19
- }
20
- else {
21
- console.log('\n[Start] Requesting guest session...');
22
- try {
23
- const guestResponse = await requestGuestKey();
24
- setGuestKey(guestResponse.api_key);
25
- apiKey = guestResponse.api_key;
26
- console.log('[Start] ✓ Guest session started\n');
27
- }
28
- catch (error) {
29
- console.error(`\n❌ Failed to get guest key: ${error.message}`);
30
- process.exit(1);
31
- }
32
- }
33
- }
34
- else if (isGuestKey()) {
35
- console.log('[Start] ✓ Guest key found\n');
36
- }
37
- else {
38
- console.log('[Start] ✓ API key found\n');
39
- }
40
- // Step 2: Check/create project config
13
+ const authResult = await resolveApiKey({
14
+ guest: options.guest,
15
+ apiKey: options.apiKey,
16
+ interactive: isAuthInteractive,
17
+ commandLabel: 'Start',
18
+ });
19
+ const apiKey = authResult.apiKey;
20
+ // Step 2: Resolve project
41
21
  console.log('[Start] Step 2/4: Checking project configuration...');
42
- let projectConfig = readProjectConfig(projectRoot);
43
- if (!projectConfig) {
44
- // Fetch available projects
45
- console.log('[Start] Fetching your projects...');
46
- try {
47
- const projects = await fetchProjects(apiKey);
48
- if (!projects || projects.length === 0) {
49
- console.error('\n❌ No projects found. Create one in the Shift dashboard first.');
50
- process.exit(1);
51
- }
52
- console.log(`[Start] Found ${projects.length} project(s)\n`);
53
- // Let user select a project
54
- const selected = await promptSelectProject(projects);
55
- // Save project config (matching extension's .shift/config.json structure)
56
- setProject(selected.project_id, selected.project_name, projectRoot);
57
- console.log(`[Start] ✓ Project "${selected.project_name}" saved to .shift/config.json\n`);
58
- projectConfig = readProjectConfig(projectRoot);
59
- }
60
- catch (error) {
61
- // If fetching fails, fall back to manual entry
62
- console.error(`\n⚠️ Could not fetch projects: ${error.message}`);
63
- console.log('Falling back to manual project ID entry...\n');
64
- const projectId = await promptProjectId();
65
- setProject(projectId, 'Unknown Project', projectRoot);
66
- console.log(`[Start] ✓ Project ID saved to .shift/config.json\n`);
67
- projectConfig = readProjectConfig(projectRoot);
68
- }
69
- }
70
- else {
71
- console.log(`[Start] ✓ Project found: ${projectConfig.project_name} (${projectConfig.project_id})\n`);
72
- }
22
+ // If guest flow returned a project_id, save it before resolving
23
+ if (authResult.projectId && !readProjectConfig(projectRoot)) {
24
+ setProject(authResult.projectId, options.projectName || 'Guest Project', projectRoot);
25
+ }
26
+ const project = await resolveProject({
27
+ apiKey,
28
+ projectId: options.projectId,
29
+ projectName: options.projectName,
30
+ template: options.template,
31
+ interactive: isProjectInteractive,
32
+ commandLabel: 'Start',
33
+ projectRoot,
34
+ });
35
+ const projectConfig = readProjectConfig(projectRoot);
73
36
  if (!projectConfig) {
74
37
  console.error('❌ Failed to configure project');
75
38
  process.exit(1);
@@ -85,7 +48,7 @@ export async function startCommand() {
85
48
  console.log('[Start] Daemon not running\n');
86
49
  // Step 4: Start daemon
87
50
  console.log('[Start] Step 4/4: Starting daemon...');
88
- const result = await startDaemon(projectRoot, projectConfig.project_id, apiKey);
51
+ const result = await startDaemon(projectRoot, project.projectId, apiKey);
89
52
  if (!result.success) {
90
53
  console.error(`\n❌ Failed to start daemon: ${result.error}`);
91
54
  process.exit(1);
@@ -94,7 +57,7 @@ export async function startCommand() {
94
57
  console.log('\n╔════════════════════════════════════════════╗');
95
58
  console.log('║ Shift is now running! ║');
96
59
  console.log('╚════════════════════════════════════════════╝');
97
- console.log('\nUse "shift status" to check connection status.');
98
- console.log('Use "shift init" to scan and index the project.');
99
- console.log('Use "shift stop" to stop the daemon.\n');
60
+ console.log('\nUse "shift-cli status" to check connection status.');
61
+ console.log('Use "shift-cli init" to scan and index the project.');
62
+ console.log('Use "shift-cli stop" to stop the daemon.\n');
100
63
  }
@@ -10,7 +10,7 @@ export async function statusCommand() {
10
10
  const apiKey = getApiKey();
11
11
  if (!apiKey) {
12
12
  console.log('API Key: ❌ Not configured');
13
- console.log('\nRun "shift start" to configure your API key.\n');
13
+ console.log('\nRun "shift-cli start" to configure your API key.\n');
14
14
  return;
15
15
  }
16
16
  if (isGuestKey()) {
@@ -23,7 +23,7 @@ export async function statusCommand() {
23
23
  const projectConfig = readProjectConfig(projectRoot);
24
24
  if (!projectConfig) {
25
25
  console.log('Project: ❌ Not configured');
26
- console.log('\nRun "shift start" to configure this project.\n');
26
+ console.log('\nRun "shift-cli start" to configure this project.\n');
27
27
  return;
28
28
  }
29
29
  console.log(`Project: ${projectConfig.project_name}`);
@@ -35,25 +35,35 @@ export async function statusCommand() {
35
35
  console.log(` - ${agent.agent_name} (${agent.agent_type})`);
36
36
  });
37
37
  }
38
- // Check project indexing status (work done)
38
+ // Check project status from backend
39
39
  try {
40
40
  const projectStatus = await fetchProjectStatus(apiKey, projectConfig.project_id);
41
+ // Init scan status
42
+ const scanStatus = projectStatus.init_scan_status ?? 'not_started';
43
+ const scanLabel = scanStatus === 'completed' ? '✓ Complete'
44
+ : scanStatus === 'in_progress' ? '⏳ In progress'
45
+ : scanStatus === 'failed' ? '❌ Failed'
46
+ : '❌ Not started';
47
+ console.log(`Init Scan: ${scanLabel}`);
48
+ // Indexed
41
49
  if (projectStatus.indexed) {
42
- console.log(`Indexed: ✓ Complete (${projectStatus.file_count} files)`);
50
+ console.log(`Indexed: ✓ ${projectStatus.file_count} files`);
43
51
  }
44
52
  else {
45
53
  console.log('Indexed: ❌ Not indexed');
46
- console.log(' Run "shift-cli init" to scan the project.');
54
+ if (scanStatus === 'not_started') {
55
+ console.log(' Run "shift-cli init" to scan the project.');
56
+ }
47
57
  }
48
58
  }
49
59
  catch {
50
- console.log('Indexed: ⚠️ Unable to check (server unavailable)');
60
+ console.log('Status: ⚠️ Unable to check (server unavailable)');
51
61
  }
52
62
  // Check daemon status
53
63
  const status = getDaemonStatus(projectRoot);
54
64
  if (!status.running) {
55
65
  console.log('Daemon: ❌ Not running');
56
- console.log('\nRun "shift start" to start the daemon.\n');
66
+ console.log('\nRun "shift-cli start" to start the daemon.\n');
57
67
  return;
58
68
  }
59
69
  console.log(`Daemon: ✓ Running (PID: ${status.pid})`);