Skip to content

feat(nowcoder): add comments command#2166

Open
aolast wants to merge 1 commit into
jackwener:mainfrom
aolast:agent/nowcoder-comments
Open

feat(nowcoder): add comments command#2166
aolast wants to merge 1 commit into
jackwener:mainfrom
aolast:agent/nowcoder-comments

Conversation

@aolast

@aolast aolast commented Jul 22, 2026

Copy link
Copy Markdown

Description

Adds a read-only nowcoder comments <id> command for mining comment content, authors, engagement, and structured reply relationships through Nowcoder's public Sparta API.

It accepts a discussion ID, moment UUID, numeric moment entity ID, or supported Nowcoder URL without requiring a browser session or login.

Comment model

Each row includes:

  • identity and structure: id, root_id, parent_id, depth, ancestry_complete
  • author tracking: author_id, author, reply_to_author_id, reply_to_author
  • mining fields: content, likes, replies, direct_replies, time, location

replies always preserves Nowcoder's server-reported total. With --with-replies, direct_replies contains direct child edges in the fetched result; without expansion it is null. Structural filtering and sorting use --min-direct-replies and --sort direct-replies.

Reply depth is reconstructed from toCommentId. If a truncated result omits an ancestor, affected rows retain their parent_id, report depth: null, and set ancestry_complete: false. Known parent edges inside incomplete components are still emitted parent-first.

The raw ip4 payload field is intentionally not exposed. The command returns the coarse API-provided ip4Location as location; stable author tracking uses author_id.

Mining controls

  • order: --order default|new|hot
  • engagement: --min-likes, --min-replies, --min-direct-replies
  • author: --author-id, --author
  • content/time: --contains, --since, --until
  • sorting: --sort thread|likes|replies|direct-replies|time
  • pagination: --limit, --replies-limit (maximum 100)

Pagination deduplicates IDs across pages and continues until the requested unique-row limit or the API's final totalPage. A short non-empty page is treated as final only when no valid totalPage is available; an empty page always stops pagination, protecting against stale page counts. Requests also retain a 100-page safety cap.

All scalar options require explicit values. The removed --parent mode is not exposed because the public reply endpoint only accepts a top-level thread root and cannot validate ownership against the requested post; --with-replies is the supported post-scoped contract.

API discovery

The endpoint mapping was derived by inspecting Nowcoder's post-detail comment UI requests and replaying the public Sparta calls:

  • discussion detail: /api/sparta/detail/content-data/detail/<id>
  • UUID moment detail: /api/sparta/detail/moment-data/detail/<uuid>
  • comments and replies: /api/sparta/comment/list-by-page

Observed entity types are 250 for discussions, 74 for moments, and 2 for replies below a top-level comment.

HTTP, JSON, envelope, record, ID, pagination, and filter failures are validated explicitly and mapped to typed OpenCLI errors. Plain-text fields preserve code-like content; HTML stripping is limited to the legacy content field.

This remains a Draft for maintainer feedback before marking it ready.

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 🌐 New site adapter
  • 📝 Documentation
  • ♻️ Refactor
  • 🔧 CI / build / tooling

Checklist

  • Relevant checks passed
  • Tests and docs updated
  • Existing Nowcoder adapter page updated
  • docs/adapters/index.md updated
  • Primary subject uses a positional argument
  • Expected failures use CliError subclasses

Live verification

opencli nowcoder comments 2878676 --limit 20 --order hot --min-replies 1 -f json
opencli nowcoder comments 2878676 --limit 20 --order hot --with-replies --replies-limit 20 --min-replies 1 -f json

For root 22795572, both runs returned replies: 1; the unexpanded row returned direct_replies: null, and the expanded row returned direct_replies: 1.

Tests

  • npm run test:adapter -- --run clis/nowcoder/comments.test.js — 17/17 passed
  • npm test — 560 files passed; 6366 tests passed, 1 skipped
  • npm run typecheck — passed
  • npm run build — passed; manifest regenerated
  • npm run docs:build — passed
  • node dist/src/main.js validate — 1302 commands, 0 errors
  • node dist/src/main.js convention-audit nowcoder/comments -f json — 0 violations
  • silent-column-drop and typed-error lint gates — no new violations

@aolast
aolast force-pushed the agent/nowcoder-comments branch 3 times, most recently from 8bdfbc6 to 5817913 Compare July 22, 2026 14:24
@aolast aolast changed the title feat(nowcoder): add get_comments command feat(nowcoder): add comments command Jul 22, 2026
@aolast
aolast force-pushed the agent/nowcoder-comments branch from 5817913 to 95f1de9 Compare July 22, 2026 14:50
@aolast
aolast force-pushed the agent/nowcoder-comments branch from 95f1de9 to f86a2ec Compare July 22, 2026 15:00
@aolast
aolast marked this pull request as ready for review July 22, 2026 15:08
@aolast

aolast commented Jul 23, 2026

Copy link
Copy Markdown
Author

Hey @jackwener , when you get a chance, could you please take a look at this PR or assign a reviewer? thanks : )

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.

1 participant