cc-viewer 1.7.12 → 1.7.14

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.
@@ -1,14 +1,14 @@
1
1
  // Local log management routes (moved verbatim from server.js handleRequest).
2
- import { existsSync, realpathSync, statSync, createReadStream, mkdtempSync, rmSync } from 'node:fs';
2
+ import { existsSync, realpathSync, statSync, createReadStream, mkdtempSync, rmSync, readdirSync } from 'node:fs';
3
3
  import { join, basename } from 'node:path';
4
4
  import { tmpdir } from 'node:os';
5
5
  import AdmZip from 'adm-zip';
6
6
  import { LOG_DIR } from '../../findcc.js';
7
7
  import { _projectName, _v2Writer } from '../interceptor.js';
8
- import { listV2Logs, listLocalLogs, countListedV1Files, deleteLogFiles, validateLogPath } from '../lib/log-management.js';
8
+ import { listV2Logs, listV2LogsPage, listLocalLogs, countListedV1Files, deleteLogFiles, validateLogPath } from '../lib/log-management.js';
9
9
  import { countLogEntries, streamRawEntriesAsync, readTailEntries } from '../lib/log-stream.js';
10
10
  import { sseHead, sseWrite, wireEnd } from '../lib/wire-compress.js';
11
- import { dirSizeSync } from '../lib/v2/layout.js';
11
+ import { dirSizeSync, sanitizePathComponent } from '../lib/v2/layout.js';
12
12
  import { extractV2Zip } from '../lib/log-zip.js';
13
13
  import { startConvert, stopConvert, convertStatus } from '../lib/v2/convert-manager.js';
14
14
  import { migrationStatus } from '../lib/v2/migrate-prompt.js';
@@ -32,18 +32,60 @@ async function localLogs(req, res, parsedUrl, isLocal, deps) {
32
32
  res.end(JSON.stringify(v1));
33
33
  return;
34
34
  }
35
- const result = listV2Logs(LOG_DIR, _projectName);
35
+ // Server-side pagination (2026-07-31): ?page=&pageSize= switches the v2
36
+ // list to a per-project page — only the requested page's sessions are
37
+ // summarized. Response shape becomes {items, total, page, pageSize} plus
38
+ // the same _-prefixed side signals below. No params = legacy grouped shape.
39
+ const pageParam = parsedUrl?.searchParams?.get('page');
40
+ let payload;
41
+ if (pageParam != null) {
42
+ // Optional ?project= views another project's logs (the modal's project
43
+ // switcher). Strict-compare against sanitizePathComponent (same pattern
44
+ // as parseV2Ref) so '..'/ separators can't traverse out of LOG_DIR;
45
+ // absent/empty falls back to the active project.
46
+ const rawProject = parsedUrl.searchParams.get('project');
47
+ let target = _projectName;
48
+ if (rawProject) {
49
+ if (rawProject !== sanitizePathComponent(rawProject)) {
50
+ res.writeHead(400, { 'Content-Type': 'application/json' });
51
+ res.end(JSON.stringify({ error: 'Invalid project name' }));
52
+ return;
53
+ }
54
+ target = rawProject;
55
+ }
56
+ const page = Math.max(1, parseInt(pageParam, 10) || 1);
57
+ const pageSize = Math.min(200, Math.max(1, parseInt(parsedUrl.searchParams.get('pageSize'), 10) || 50));
58
+ payload = listV2LogsPage(LOG_DIR, target, { page, pageSize });
59
+ // _currentProject must stay the ACTIVE project (_projectName), not the
60
+ // viewed one (listV2LogsPage sets it to `target`): the frontend's global
61
+ // currentProject drives the sidebar / migration counts / v1 banner, and
62
+ // the viewed project is carried separately by its own logViewProject
63
+ // state. Overwriting it here would let "viewing project A" leak into
64
+ // global state. _viewedProject tells the client which project this page
65
+ // actually lists.
66
+ payload._currentProject = _projectName || '';
67
+ payload._viewedProject = target || '';
68
+ // Project list for the modal's switcher dropdown. LOG_DIR's top level
69
+ // holds one dir per project (recycle dirs live INSIDE each project, so
70
+ // nothing to filter here) — but skip dot-prefixed hidden dirs.
71
+ try {
72
+ payload._allProjects = readdirSync(LOG_DIR, { withFileTypes: true })
73
+ .filter(e => e.isDirectory() && !e.name.startsWith('.')).map(e => e.name).sort();
74
+ } catch { payload._allProjects = []; }
75
+ } else {
76
+ payload = listV2Logs(LOG_DIR, _projectName);
77
+ }
36
78
  // Legacy v1 files are not in this list — surface two distinct signals:
37
79
  // - _v1FileCount: v1 files ON DISK (gates the v1-view entry link; the
38
80
  // converter never deletes sources, so this outlives a finished migration)
39
81
  // - _unmigratedV1Count/Bytes: files still AWAITING migration (gates the
40
82
  // migrate button + hint inside the v1 view and the startup prompt)
41
83
  const mig = migrationStatus(LOG_DIR, _projectName || '');
42
- result._unmigratedV1Count = mig.files;
43
- result._unmigratedV1Bytes = mig.totalBytes;
44
- result._v1FileCount = _projectName ? countListedV1Files(join(LOG_DIR, _projectName)) : 0;
84
+ payload._unmigratedV1Count = mig.files;
85
+ payload._unmigratedV1Bytes = mig.totalBytes;
86
+ payload._v1FileCount = _projectName ? countListedV1Files(join(LOG_DIR, _projectName)) : 0;
45
87
  res.writeHead(200, { 'Content-Type': 'application/json' });
46
- res.end(JSON.stringify(result));
88
+ res.end(JSON.stringify(payload));
47
89
  } catch (err) {
48
90
  res.writeHead(500, { 'Content-Type': 'application/json' });
49
91
  res.end(JSON.stringify({ error: err.message }));
@@ -14,6 +14,9 @@ IMPORTANT: Never generate or guess URLs unless you are confident they help the u
14
14
 
15
15
  # Doing tasks
16
16
  - Read the relevant files before acting or answering; ground every claim and change in code you have actually looked at.
17
+ - Read once with enough context instead of nibbling: prefer one wide Read (or a Grep for the exact line range) over many small Reads.
18
+ - Self-check for repetition: if you have already read the same file twice, do not read it a third time — stop and answer from what you have. Never re-read the same lines with only the offset or limit changed.
19
+ - Convergence budget: once you have enough evidence to answer, stop searching and answer; a partial report beats endless exploration.
17
20
  - When a request could be read either as a question or as a change to make, treat it as a task and carry it out. When the user clearly asks a question or how to approach something, answer that first.
18
21
  - Deliver exactly what was asked and nothing more: no unrequested CLI wrappers, configuration options, logging, progress output, or abstractions. This is very important to your performance.
19
22
  - Never assume a library or framework is available — check the project's manifest or neighboring files before using it.
@@ -26,6 +29,7 @@ IMPORTANT: Never generate or guess URLs unless you are confident they help the u
26
29
  - Do not narrate tool calls; the calls themselves show the user what you are doing.
27
30
  - Send independent tool calls together in one response instead of one at a time.
28
31
  - Track multi-step work explicitly and mark each step done as you finish it.
32
+ - Every ten tool calls, write one line saying what you have confirmed and what is still missing; if you cannot, stop calling tools and report what you have.
29
33
  - Tool results and user messages may include <system-reminder> tags. They carry information from the system, not from the user.
30
34
 
31
35
  # Executing actions with care
@@ -13,6 +13,10 @@ IMPORTANT: Never generate or guess URLs unless you are confident they help the u
13
13
 
14
14
  # Doing tasks
15
15
  - Read the relevant files before acting or answering; ground every claim and change in code you have actually looked at.
16
+ - Before your first tool call, output a one-sentence action plan; then act.
17
+ - Read once with enough context instead of nibbling: prefer one wide Read (or a Grep for the exact line range) over many small Reads.
18
+ - Self-check for repetition: if you have already read the same file twice, do not read it a third time — stop and answer from what you have. Never re-read the same lines with only the offset or limit changed.
19
+ - Convergence budget: once you have enough evidence to answer, stop searching and answer; a partial report beats endless exploration.
16
20
  - When a request could be read either as a question or as a change to make, treat it as a task and carry it out. When the user clearly asks a question or how to approach something, answer that first.
17
21
  - Deliver exactly what was asked and nothing more: no unrequested CLI wrappers, configuration options, logging, progress output, or abstractions. This is very important to your performance.
18
22
  - Never assume a library or framework is available — check the project's manifest or neighboring files before using it.
@@ -25,6 +29,7 @@ IMPORTANT: Never generate or guess URLs unless you are confident they help the u
25
29
  - Do not narrate tool calls; the calls themselves show the user what you are doing.
26
30
  - Send independent tool calls together in one response instead of one at a time.
27
31
  - Track multi-step work explicitly and mark each step done as you finish it.
32
+ - Every ten tool calls, write one line saying what you have confirmed and what is still missing; if you cannot, stop calling tools and report what you have.
28
33
  - Tool results and user messages may include <system-reminder> tags. They carry information from the system, not from the user.
29
34
 
30
35
  # Executing actions with care