Skip to content

feat(logs): add --search and --cursor to logs:get --type server - #273

Merged
Harshi-Shah-CS merged 11 commits into
v2-devfrom
CL-7693
Nov 2, 2026
Merged

Harshi-Shah-CS merged 11 commits into
v2-devfrom
CL-7693

Conversation

@Harshi-Shah-CS

Copy link
Copy Markdown
Contributor

Ticket: https://contentstack.atlassian.net/browse/CL-7693 (follows CL-7171 / #269; the backend is CL-7180)

What

  • --search <text> and --cursor <cursor> on launch:logs:get --type server.
    • Both are server-only: with --type deployment or live the command exits 2 before reading any logs.
    • --search is trimmed and capped at 256 characters, the logs service's own limit.
    • --cursor is opaque; the CLI never parses it.
  • A window is read in full, oldest first, without holding it in memory. The CLI reads one page at a time (sortDirection=asc), follows pageInfo.newestCursor with the same window and search, and prints each page as it arrives.
    • It stops when the server reports nothing newer, on an empty page, when a page has no cursor, or after MAX_PAGES (100) pages.
    • The old 5000-line truncation notice is gone.
  • Resume command. At the page cap, or on Ctrl-C (exit 3, after the page in hand is printed), it prints a ready-to-run Resume with: csdx launch:logs:get … --cursor '<cursor>'.
    • That command's --since/--until are always the run's absolute window. A relative --since would be recalculated on resume, move the start past the cursor, and silently skip the logs in between.
    • Values are single-quoted for a POSIX shell.
  • Errors in the CLI's own words for INVALID_CURSOR, SEARCH_TOO_LONG, INVALID_SOURCE and INVALID_SORT_DIRECTION, including the field-keyed error body the real service sends.
  • Guard for a logs service without CL-7180. If --search or --cursor was sent and the response has no pageInfo, the command exits 1 instead of printing unfiltered logs as matches or restarting the window. A plain window still works against either service.
  • When nothing matches, the message names the search: No server logs matched "<text>" between ….
  • The README is regenerated, and AGENTS.md documents the cursor walk.

Decisions:

  • --search with --type live is refused rather than filtered on the client.
  • Ctrl-C waits for the request in flight, as the deployment watcher already does.

Tests

  • Unit tests:
    • flag rules and the 256/257 boundary
    • the request query with and without search/cursor
    • every end of the walk, including the exact MAX_PAGES boundary (proved by mutating < to <=)
    • a failure on a later page
    • resume-line wording and quoting
    • Ctrl-C mid-walk
    • each error code
    • the old-service guard
  • Integration tests (nock) on the wire:
    • a two-page walk carrying the cursor
    • 100 requests from a server that always has more, then the resume command
    • Ctrl-C mid-walk: exit 3, no further request, SIGINT listener released
    • the field-keyed INVALID_CURSOR
    • the old-service guard
  • npm test: 3446 passed. npm run lint is clean. .talismanrc checksums are refreshed for the touched test files and docs.
  • Live: the harness case cases/89-logs-get.sh is in contentstack/contentfly-dev-workspace#159. The search and cursor cases need CL-7180 deployed to the target environment. It's still Ready to Deploy in Jira, and on an environment without it they skip.
  • Still to do outside this repo: the user docs, migration guide, Commands Details page and TRD §12.

#claude_code#
🤖 Generated with Claude Code

Harshi-Shah-CS and others added 9 commits October 30, 2026 16:30
logs:get declares --search (trimmed, at most 256 characters through the
shared withinLength check, the logs service limit) and --cursor (opaque,
trimmed). Both are server-only: the window rule becomes onlyWithServer,
which takes any catalog flag, so --type deployment or live with either
exits 2 before any log read.

#claude_code#
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
ServerLogsApi.page reads one page with sortDirection=asc, sending search
and cursor only when given, and returns the logs with the server's
pageInfo. ServerLogsApi.pages follows pageInfo.newestCursor with the
same window and search, and stops when the server reports nothing newer,
sends no pageInfo (a logs service without CL-7180), an empty page or no
cursor, or after MAX_PAGES requests. A page that fails rejects the walk
after the pages already read.

#claude_code#
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
… cursor

logs:get --type server now walks ServerLogsApi.pages with the resolved
window, --search and --cursor, printing each page as it arrives, so a
window past one page is printed in full and in order without holding it
in memory. The single windowed read, its 5000-line cap notice and
SERVER_LOGS_PAGE_CAP are gone. Every server-log request now carries
sortDirection=asc.

#claude_code#
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…page cap

When the walk stops after MAX_PAGES pages with the last page still
reporting newer logs, logs:get prints a yellow notice and a ready-to-run
command that resumes from that page's newest cursor. The window is
printed as absolute ISO times, never the relative --since/--until the
user typed: re-resolving a relative --since on resume would move the
start past the cursor and silently skip the logs in between. Search
and cursor are single-quoted for a POSIX shell. nextCursorOf is the one
rule for "this page leads to another", shared by the walk and the hint.

#claude_code#
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
logs:get --type server now runs inside the same onInterrupt wrapper as
the deployment and live follows. Ctrl-C lets the page in flight finish
printing, requests no further page, prints "Stopped following the logs."
and the resume command from the last printed page's newest cursor, and
exits 3 with the listener released. untilInterrupted takes the extra
lines to print after the stop line.

#claude_code#
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
LOGS_ERROR_MESSAGES rewords the four codes the logs service added with
CL-7180. INVALID_CURSOR says the cursor did not come from logs:get and
to run again without --cursor. SEARCH_TOO_LONG repeats the 256-character
limit. INVALID_SOURCE and INVALID_SORT_DIRECTION can only follow a CLI
bug, since the CLI never sends source and always sends asc, so they ask
for an update. The field-keyed body the real service sends is covered on
the wire.

#claude_code#
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
An empty --search result now reads 'No server logs matched "<text>"
between <start> and <end>.' instead of the generic no-logs line, so an
empty result is not mistaken for an empty window.

.talismanrc: refreshed the checksums of the three test files this
branch changed (logs-get.test.ts, get.test.ts, resources.test.ts).

#claude_code#
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
README carries the regenerated logs:get usage with --search and --cursor.
AGENTS.md describes the walk: oldest-first pages over newestCursor,
nextCursorOf as the one continuation rule, the MAX_PAGES end, the resume
command with an absolute window, and Ctrl-C during the walk exiting 3.

.talismanrc: refreshed the README.md and AGENTS.md checksums and added
src/logs/logs.inputs.test.ts. Talisman flags words like key, password
and --var in them; none holds a secret.

#claude_code#
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
… them

A logs service without CL-7180 returns no pageInfo and drops search and
cursor, so --search would print every log in the window as if it matched
and --cursor would start the window over. ServerLogsApi.page now exits 1
with "The Launch API in this region does not support --search or
--cursor for server logs yet." when either was sent and no pageInfo came
back. A plain window still works against either service.

.talismanrc: refreshed the logs-get.test.ts checksum.

#claude_code#
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@Harshi-Shah-CS
Harshi-Shah-CS requested review from a team as code owners October 30, 2026 12:19
@snyk-io

snyk-io Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues
✅ Licenses 0 0 0 0 0 issues
✅ Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@github-actions

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 6 9 25 ✅ Passed
🟡 Medium Severity 0 2 500 ✅ Passed
🔵 Low Severity 0 0 1000 ✅ Passed

⏱️ SLA Breach Summary

✅ No SLA breaches detected. All vulnerabilities are within acceptable time thresholds.

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 0 30 / 120 days ✅ Passed
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

ℹ️ Vulnerabilities Without Available Fixes (Informational Only)

The following vulnerabilities were detected but do not have fixes available (no upgrade or patch). These are excluded from failure thresholds:

  • Critical without fixes: 0
  • High without fixes: 9
  • Medium without fixes: 2
  • Low without fixes: 0

✅ BUILD PASSED - All security checks passed

SakshiKoli-CS
SakshiKoli-CS previously approved these changes Oct 30, 2026

@dhruv-parekh-cs dhruv-parekh-cs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the whole PR: 0 high, 1 medium (inline).

Cross-repo (CL-7693): the harness cases in contentfly-dev-workspace#159 match the flags and output here (--search, --cursor, Resume with:, Stopped after). Merge this PR first; #159's cases skip cleanly where CL-7180 isn't deployed.

— 🤖 launch-pr-review-agent (Claude)


Generated by Claude Code

Comment thread src/logs/server-logs.api.ts Resolved
Harshi-Shah-CS and others added 2 commits November 2, 2026 10:27
Address review (dhruv-parekh-cs): a logs service before CL-7180 caps a
window at its newest 5000 lines and sends no pageInfo, so the walk ends
after one page and nextCursorOf gives no resume command. The truncation
went silent. logs:get --type server now prints the old notice, "Showing
the newest 5000 server log lines in this window. Narrow --since/--until
to see earlier ones.", when the last page has no pageInfo and holds
exactly SERVER_LOGS_PAGE_CAP lines. With CL-7180 deployed pageInfo is
always present and the resume command covers truncation.

.talismanrc: refreshed the checksums of get.test.ts and logs-get.test.ts.

#claude_code#
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Brings in launch:secrets (#275). The only conflict was .talismanrc: the
README.md and src/resources.test.ts entries now carry the checksums of
the merged files.

#claude_code#
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@Harshi-Shah-CS

Copy link
Copy Markdown
Contributor Author

Review round 1, handled.

Fixed

  • Medium: the 5000-line truncation was silent on a logs service before CL-7180 (src/logs/server-logs.api.ts). Verified and fixed in 92592d3: logs:get --type server again prints Showing the newest 5000 server log lines in this window. Narrow --since/--until to see earlier ones. when the last page has no pageInfo and holds exactly 5000 lines. Covered by unit tests (5000 shows the notice, 4999 doesn't), a wording test, and the old response shape on the wire (T54). The thread is resolved. Correction to my reply there: the logs-service constant is LAST_FEW_LOGS_SIZE, not LAUNCH_FEW_LOGS_SIZE.

Also on the branch: v2-dev was merged in (b29c21c) to clear the conflict with #275 (launch:secrets). The only conflict was the README.md and src/resources.test.ts checksums in .talismanrc, now set to the merged files. Full suite: 3806 passed; lint and tsc clean.

Disputed: none. Left for a human: none.

— Claude Code

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 6 9 25 ✅ Passed
🟡 Medium Severity 5 7 500 ✅ Passed
🔵 Low Severity 0 0 1000 ✅ Passed

⏱️ SLA Breach Summary

✅ No SLA breaches detected. All vulnerabilities are within acceptable time thresholds.

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 0 30 / 120 days ✅ Passed
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

ℹ️ Vulnerabilities Without Available Fixes (Informational Only)

The following vulnerabilities were detected but do not have fixes available (no upgrade or patch). These are excluded from failure thresholds:

  • Critical without fixes: 0
  • High without fixes: 9
  • Medium without fixes: 7
  • Low without fixes: 0

✅ BUILD PASSED - All security checks passed

@dhruv-parekh-cs dhruv-parekh-cs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review since ec8c3e5 (92592d3, the 5000-line notice for a logs service without page info; the v2-dev merge itself not reviewed): no high or medium issues.

Cross-repo (CL-7693): contentfly-dev-workspace#159's no-match search case expects wording this CLI doesn't print; flagged there. Merge order as stated: this PR first, then #159.

— 🤖 launch-pr-review-agent (Claude)


Generated by Claude Code

@Harshi-Shah-CS
Harshi-Shah-CS merged commit 7021b6c into v2-dev Nov 2, 2026
7 checks passed
@Harshi-Shah-CS
Harshi-Shah-CS deleted the CL-7693 branch November 2, 2026 05:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants