/ clis / lesswrong / comments.js
comments.js
 1  import { cli, Strategy } from '@jackwener/opencli/registry';
 2  import { EmptyResultError } from '@jackwener/opencli/errors';
 3  import { DOMAIN, SITE, gqlEscape, gqlRequest, parsePostId, stripHtml, } from './_helpers.js';
 4  cli({
 5      site: SITE,
 6      name: 'comments',
 7      description: 'Top comments on a post',
 8      domain: DOMAIN,
 9      strategy: Strategy.PUBLIC,
10      browser: false,
11      args: [
12          {
13              name: 'url-or-id',
14              type: 'string',
15              required: true,
16              positional: true,
17              help: 'Post URL or LessWrong post ID',
18          },
19          { name: 'limit', type: 'int', default: 5, help: 'Number of comments' },
20      ],
21      columns: ['rank', 'score', 'author', 'text'],
22      func: async (_page, kwargs) => {
23          const postId = gqlEscape(parsePostId(String(kwargs['url-or-id'])));
24          const limit = Number(kwargs.limit ?? 5);
25          // Fetch post title and comments in parallel
26          const [postData, commentsData] = await Promise.all([
27              gqlRequest(`query PostTitle {
28          post(input: {selector: {documentId: "${postId}"}}) {
29            result { _id title slug }
30          }
31        }`),
32              gqlRequest(`query Comments {
33          comments(input: {terms: {view: "postCommentsTop", postId: "${postId}", limit: ${limit}}}) {
34            results { _id user { displayName } baseScore htmlBody postedAt }
35          }
36        }`),
37          ]);
38          const post = postData?.post?.result;
39          if (!post?._id) {
40              throw new EmptyResultError('lesswrong comments', `Post "${postId}" not found`);
41          }
42          const comments = (commentsData?.comments?.results ?? []);
43          const rows = [];
44          // First row: post context
45          rows.push({
46              rank: '',
47              score: '',
48              author: '',
49              text: `Comments on: ${post.title ?? 'Untitled'} (https://${DOMAIN}/posts/${post._id}/${post.slug})`,
50          });
51          for (let i = 0; i < comments.length; i++) {
52              const item = comments[i];
53              const user = item.user;
54              const raw = stripHtml(item.htmlBody ?? '');
55              rows.push({
56                  rank: i + 1,
57                  score: item.baseScore ?? 0,
58                  author: user?.displayName ?? 'Unknown',
59                  text: raw.length > 500 ? `${raw.slice(0, 500)}...` : raw,
60              });
61          }
62          return rows;
63      },
64  });