File size: 3,596 Bytes
a5d1c1b
 
 
 
 
 
 
 
61b1da1
a5d1c1b
 
61b1da1
a5d1c1b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61b1da1
a5d1c1b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import pc from 'picocolors';
import { projectConfigManager } from '../config/project-config.js';
import { cacheService } from '../services/cache-service.js';
import { authService } from '../services/auth-service.js';
import { parseRepoUrl } from '../services/sync-service.js';
import { outputResult, outputError, OutputOptions } from '../utils/output.js';

export async function handleStatus(options: OutputOptions = {}): Promise<void> {
  const workspaceRoot = projectConfigManager.findEvbRoot();
  if (!workspaceRoot) {
    return outputError(
      'Not inside an Ever-Brain project. Run `evb init <repo>` first.',
      'NOT_IN_WORKSPACE',
      options
    );
  }

  try {
    const config = projectConfigManager.readConfig(workspaceRoot);
    const state = projectConfigManager.readState(workspaceRoot);
    const dirty = cacheService.computeDirtyState(workspaceRoot);
    const cachedFiles = cacheService.listCachedFiles(workspaceRoot);

    const { owner, repo } = parseRepoUrl(config.source.repository);

    // Auth info
    const token = authService.resolveToken(undefined, workspaceRoot);
    let username: string | undefined;
    let permission: string = 'none';

    if (token) {
      try {
        const user = await authService.validateToken(token);
        username = user.username;
        permission = await authService.getRepoPermission(owner, repo, username, token);
      } catch {}
    }

    const knowledgeCount = cachedFiles.filter((f) => f.startsWith('knowledge/')).length;
    const skillsCount = cachedFiles.filter((f) => f.startsWith('skills/') && f.endsWith('.md')).length;

    const data = {
      workspace: workspaceRoot,
      repository: config.source.repository,
      branch: config.source.branch,
      apiUrl: projectConfigManager.getApiUrl(workspaceRoot),
      lastSync: state?.last_sync || null,
      cachedFilesCount: cachedFiles.length,
      knowledgeCount,
      skillsCount,
      authenticatedAs: username || null,
      permission,
      isDirty: dirty.isDirty,
      modifications: {
        modified: dirty.modified,
        added: dirty.added,
        deleted: dirty.deleted,
      },
    };

    outputResult(data, options, () => {
      console.log(pc.bold(pc.cyan('Ever-Brain Workspace Status')));
      console.log(`  Source:       ${pc.white(config.source.repository)} (branch: ${pc.green(config.source.branch)})`);
      console.log(`  API Target:   ${pc.dim(projectConfigManager.getApiUrl(workspaceRoot))}`);
      console.log(`  Last Sync:    ${state?.last_sync ? pc.white(state.last_sync) : pc.yellow('never')}`);
      console.log(`  Cached:       ${cachedFiles.length} files (${knowledgeCount} knowledge, ${skillsCount} skills)`);

      if (username) {
        console.log(`  Auth:         @${username} (Permission: ${permission})`);
      } else {
        console.log(`  Auth:         ${pc.dim('Anonymous (read-only)')}`);
      }

      console.log('');
      if (!dirty.isDirty) {
        console.log(pc.green('  Working tree clean (no unpushed modifications)'));
      } else {
        console.log(pc.yellow('  Local Modifications (Unpushed):'));
        for (const m of dirty.modified) {
          console.log(`    ${pc.yellow('M')} ${m}`);
        }
        for (const a of dirty.added) {
          console.log(`    ${pc.green('A')} ${a}`);
        }
        for (const d of dirty.deleted) {
          console.log(`    ${pc.red('D')} ${d}`);
        }
      }
    });
  } catch (err: unknown) {
    const message = err instanceof Error ? err.message : String(err);
    outputError(message, 'STATUS_ERROR', options);
  }
}