@a9n-shoji/rvw 0.10.0 → 0.11.0

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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,18 @@
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.11.0] - 2026-10-02
9
+
10
+ ### Added
11
+
12
+ - PR一覧にアーカイブ・解除と、既定ONの「アーカイブ済みを非表示」を追加。Closed / Mergedの絞り込みと独立して利用できます。
13
+ - 独自Skillから操作できる`rvw pr archive`、`rvw pr unarchive`、`rvw pr list`と対応APIを追加。Machine protocolは6を維持し、`pullRequest.archive`と`pullRequest.list`を追加。
14
+
15
+ ### Changed
16
+
17
+ - アーカイブ状態はローカルDBへ保存し、同期・reset後も維持。アーカイブ済みでも直接閲覧・コメントを継続できます。同梱Skillによる自動アーカイブは行いません。
18
+ - 最終ページが空になった場合の自動補正はブラウザ履歴を置き換え、「戻る」がループしないようにしました。
19
+
8
20
  ## [0.10.0] - 2026-09-23
9
21
 
10
22
  ### Added
package/README.md CHANGED
@@ -154,6 +154,11 @@ default / namespace / package import、re-export、tsconfig paths、完全なmod
154
154
 
155
155
  ---
156
156
 
157
+ ## 見終わったPRを整理する
158
+
159
+ PR一覧の各行からアーカイブ・解除できます。アーカイブ済みは既定で非表示になり、チェックを外すと再表示できます。
160
+ PRの閲覧やコメントは引き続き利用できます。[操作と独自Skillでの自動化](https://github.com/a9n-shoji/rvw/blob/main/docs/usage.md#pr一覧のアーカイブ)を参照してください。
161
+
157
162
  ## ドキュメント
158
163
 
159
164
  ソースから `pnpm demo` を実行すると、デモ環境(認証・Agent不要)をローカルで試せます。
package/dist/cli.mjs CHANGED
@@ -18753,7 +18753,7 @@ function parseWalkthroughUri(uri) {
18753
18753
  }
18754
18754
 
18755
18755
  // src/shared/constants.ts
18756
- var APP_VERSION = "0.10.0";
18756
+ var APP_VERSION = "0.11.0";
18757
18757
  var PROTOCOL_VERSION = 6;
18758
18758
  var VIEWER_ID_HEADER = "x-rvw-viewer-id";
18759
18759
  var VIEWER_OPEN_LEASE_HEADER = "x-rvw-viewer-open-lease";
@@ -19014,6 +19014,7 @@ function mapPullRequest(row) {
19014
19014
  githubState: nullableGitHubPullRequestState(row, "github_state"),
19015
19015
  githubIsDraft: nullableBoolean(row, "github_is_draft"),
19016
19016
  githubApprovalCount: nullableNumber(row, "github_approval_count"),
19017
+ archivedAt: nullableString(row, "archived_at"),
19017
19018
  fetchedAt: stringValue(row, "fetched_at"),
19018
19019
  createdAt: stringValue(row, "created_at"),
19019
19020
  updatedAt: stringValue(row, "updated_at")
@@ -19566,7 +19567,7 @@ var RvwDatabase = class {
19566
19567
  "SELECT * FROM pull_requests WHERE github_state = 'OPEN' OR github_state IS NULL ORDER BY updated_at DESC"
19567
19568
  ).all().map(mapPullRequest);
19568
19569
  }
19569
- listPullRequestSummaries(offset, limit, hideClosedOrMerged = true) {
19570
+ listPullRequestSummaries(offset, limit, hideClosedOrMerged = true, hideArchived = true) {
19570
19571
  const hideClosedOrMergedValue = hideClosedOrMerged ? 1 : 0;
19571
19572
  const rows = this.database.prepare(
19572
19573
  `WITH page AS (
@@ -19580,9 +19581,10 @@ var RvwDatabase = class {
19580
19581
  github_updated_at,
19581
19582
  github_state,
19582
19583
  github_is_draft,
19583
- github_approval_count
19584
+ github_approval_count,
19585
+ archived_at
19584
19586
  FROM pull_requests
19585
- WHERE ? = 0 OR github_state IS NULL OR github_state = 'OPEN'
19587
+ WHERE (? = 0 OR github_state IS NULL OR github_state = 'OPEN') AND (? = 0 OR archived_at IS NULL)
19586
19588
  ORDER BY github_updated_at DESC, id DESC
19587
19589
  LIMIT ? OFFSET ?
19588
19590
  ), comment_counts AS (
@@ -19615,6 +19617,7 @@ var RvwDatabase = class {
19615
19617
  pr.github_state,
19616
19618
  pr.github_is_draft,
19617
19619
  pr.github_approval_count,
19620
+ pr.archived_at,
19618
19621
  COALESCE(comment_counts.unresolved_count, 0) AS unresolved_comment_count,
19619
19622
  COALESCE(comment_counts.resolved_count, 0) AS resolved_comment_count,
19620
19623
  COALESCE(walkthrough_counts.walkthrough_count, 0) AS walkthrough_count,
@@ -19624,10 +19627,10 @@ var RvwDatabase = class {
19624
19627
  LEFT JOIN walkthrough_counts ON walkthrough_counts.pull_request_id = pr.id
19625
19628
  LEFT JOIN structure_counts ON structure_counts.pull_request_id = pr.id
19626
19629
  ORDER BY pr.github_updated_at DESC, pr.id DESC`
19627
- ).all(hideClosedOrMergedValue, limit, offset);
19630
+ ).all(hideClosedOrMergedValue, hideArchived ? 1 : 0, limit, offset);
19628
19631
  const totalRow = this.database.prepare(
19629
- "SELECT COUNT(*) AS total FROM pull_requests WHERE ? = 0 OR github_state IS NULL OR github_state = 'OPEN'"
19630
- ).get(hideClosedOrMergedValue);
19632
+ "SELECT COUNT(*) AS total FROM pull_requests WHERE (? = 0 OR github_state IS NULL OR github_state = 'OPEN') AND (? = 0 OR archived_at IS NULL)"
19633
+ ).get(hideClosedOrMergedValue, hideArchived ? 1 : 0);
19631
19634
  if (!totalRow) throw new RvwError("DATABASE_ERROR", "Pull Request\u4EF6\u6570\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3002");
19632
19635
  return {
19633
19636
  items: rows.map((row) => ({
@@ -19641,6 +19644,7 @@ var RvwDatabase = class {
19641
19644
  githubState: nullableGitHubPullRequestState(row, "github_state"),
19642
19645
  githubIsDraft: nullableBoolean(row, "github_is_draft"),
19643
19646
  githubApprovalCount: nullableNumber(row, "github_approval_count"),
19647
+ archivedAt: nullableString(row, "archived_at"),
19644
19648
  unresolvedCommentCount: numberValue(row, "unresolved_comment_count"),
19645
19649
  resolvedCommentCount: numberValue(row, "resolved_comment_count"),
19646
19650
  walkthroughCount: numberValue(row, "walkthrough_count"),
@@ -19649,6 +19653,18 @@ var RvwDatabase = class {
19649
19653
  total: numberValue(totalRow, "total")
19650
19654
  };
19651
19655
  }
19656
+ setPullRequestArchived(id, archived) {
19657
+ return this.immediateTransaction(() => {
19658
+ const current = this.getPullRequest(id);
19659
+ if (!current)
19660
+ throw new RvwError("PR_NOT_FOUND", "Pull Request\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002", { status: 404 });
19661
+ if (current.archivedAt !== null === archived) return current;
19662
+ const archivedAt = archived ? (/* @__PURE__ */ new Date()).toISOString() : null;
19663
+ this.database.prepare("UPDATE pull_requests SET archived_at = ? WHERE id = ?").run(archivedAt, id);
19664
+ this.incrementDomainRevisions(["pullRequests"]);
19665
+ return { ...current, archivedAt };
19666
+ });
19667
+ }
19652
19668
  updatePullRequestGitHubStatuses(updates) {
19653
19669
  if (updates.length === 0) return;
19654
19670
  this.immediateTransaction(() => {
@@ -43057,6 +43073,9 @@ var RvwService = class {
43057
43073
  throw new RvwError("PR_NOT_FOUND", "Pull Request\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002", { status: 404 });
43058
43074
  return pullRequest;
43059
43075
  }
43076
+ setPullRequestArchived(id, archived) {
43077
+ return this.database.setPullRequestArchived(id, archived);
43078
+ }
43060
43079
  listPullRequests(input) {
43061
43080
  const offset = input.offset ?? 0;
43062
43081
  const limit = input.limit ?? DEFAULT_PULL_REQUEST_LIST_LIMIT;
@@ -43070,7 +43089,12 @@ var RvwService = class {
43070
43089
  `limit\u306F1\u4EE5\u4E0A${MAX_PULL_REQUEST_LIST_LIMIT}\u4EE5\u4E0B\u306E\u6574\u6570\u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002`
43071
43090
  );
43072
43091
  }
43073
- const page = this.database.listPullRequestSummaries(offset, limit, hideClosedOrMerged);
43092
+ const page = this.database.listPullRequestSummaries(
43093
+ offset,
43094
+ limit,
43095
+ hideClosedOrMerged,
43096
+ input.hideArchived ?? true
43097
+ );
43074
43098
  const returned = page.items.length;
43075
43099
  const hasMore = offset + returned < page.total;
43076
43100
  return {
@@ -49938,6 +49962,13 @@ var structurePublishInputSchema = external_exports.object({
49938
49962
  }).strict().superRefine(refineStructureContent);
49939
49963
  var agentCommandInputSchemas = {
49940
49964
  doctor: external_exports.object({ cwd: nonEmptyString }).strict(),
49965
+ "pr.list": external_exports.object({
49966
+ offset: external_exports.number().int().min(0).default(0),
49967
+ limit: external_exports.number().int().min(1).max(MAX_PULL_REQUEST_LIST_LIMIT).default(DEFAULT_PULL_REQUEST_LIST_LIMIT),
49968
+ hideClosedOrMerged: external_exports.boolean().default(true),
49969
+ hideArchived: external_exports.boolean().default(true)
49970
+ }).strict(),
49971
+ "pr.archive": external_exports.object({ reference: nonEmptyString, archived: external_exports.boolean() }).strict(),
49941
49972
  "pr.refresh": external_exports.object({ reference: nonEmptyString }).strict(),
49942
49973
  "pr.sync": pullRequestSyncInputSchema.extend({
49943
49974
  repositoryPath: nonEmptyString.optional(),
@@ -50013,6 +50044,7 @@ var openPullRequestSchema = external_exports.object({
50013
50044
  reference: external_exports.string().min(1).optional(),
50014
50045
  cwd: external_exports.string().min(1)
50015
50046
  });
50047
+ var pullRequestArchiveSchema = external_exports.object({ archived: external_exports.boolean() }).strict();
50016
50048
  var resetSchema = external_exports.object({ yes: external_exports.boolean() });
50017
50049
  var structureDeleteSchema = external_exports.object({ expectedUpdatedAt: external_exports.string().min(1).max(100) });
50018
50050
  var viewerIdSchema = external_exports.uuid();
@@ -50021,6 +50053,7 @@ var themePreferenceSchema = external_exports.object({ themePreference: external_
50021
50053
  var pullRequestListQuerySchema = external_exports.object({
50022
50054
  offset: external_exports.coerce.number().int().min(0).default(0),
50023
50055
  limit: external_exports.coerce.number().int().min(1).max(MAX_PULL_REQUEST_LIST_LIMIT).default(DEFAULT_PULL_REQUEST_LIST_LIMIT),
50056
+ hideArchived: external_exports.enum(["true", "false"]).default("true").transform((value) => value === "true"),
50024
50057
  hideClosedOrMerged: external_exports.enum(["true", "false"]).default("true").transform((value) => value === "true")
50025
50058
  });
50026
50059
  var createCommentSchema = external_exports.object({
@@ -50229,10 +50262,18 @@ function createApp(service, options) {
50229
50262
  const query = pullRequestListQuerySchema.parse({
50230
50263
  offset: context.req.query("offset"),
50231
50264
  limit: context.req.query("limit"),
50265
+ hideArchived: context.req.query("hideArchived"),
50232
50266
  hideClosedOrMerged: context.req.query("hideClosedOrMerged")
50233
50267
  });
50234
50268
  return context.json({ ok: true, ...service.listPullRequests(query) });
50235
50269
  });
50270
+ app.patch("/api/pull-requests/:id/archive", async (context) => {
50271
+ const input = pullRequestArchiveSchema.parse(await context.req.json());
50272
+ return context.json({
50273
+ ok: true,
50274
+ pullRequest: service.setPullRequestArchived(context.req.param("id"), input.archived)
50275
+ });
50276
+ });
50236
50277
  app.post(
50237
50278
  "/api/pull-requests/refresh-statuses",
50238
50279
  async (context) => context.json({ ok: true, ...await service.refreshPullRequestStatuses() })
@@ -51019,6 +51060,16 @@ async function dispatchAgentSocketRequest(service, rawRequest) {
51019
51060
  const input = parseOperationInput("doctor", request.input);
51020
51061
  return await service.doctor(input.cwd);
51021
51062
  }
51063
+ case "pr.list": {
51064
+ return service.listPullRequests(parseOperationInput("pr.list", request.input));
51065
+ }
51066
+ case "pr.archive": {
51067
+ const input = parseOperationInput("pr.archive", request.input);
51068
+ return service.setPullRequestArchived(
51069
+ service.resolveStoredPullRequest(input.reference).id,
51070
+ input.archived
51071
+ );
51072
+ }
51022
51073
  case "pr.refresh": {
51023
51074
  const input = parseOperationInput("pr.refresh", request.input);
51024
51075
  return await service.refreshByReference(input.reference);
@@ -52840,6 +52891,8 @@ function createProgram(runtimeFactory = defaultRuntimeFactory) {
52840
52891
  "comment.resolve",
52841
52892
  "comment.reopen",
52842
52893
  "pullRequest.sync",
52894
+ "pullRequest.list",
52895
+ "pullRequest.archive",
52843
52896
  "structure.list",
52844
52897
  "structure.read",
52845
52898
  "structure.preview",
@@ -52906,6 +52959,47 @@ function createProgram(runtimeFactory = defaultRuntimeFactory) {
52906
52959
  }
52907
52960
  });
52908
52961
  const pr = program2.command("pr").description("Pull Request\u72B6\u614B\u3092\u7BA1\u7406");
52962
+ pr.command("list").option("--json", "JSON\u3067\u51FA\u529B").option("--offset <offset>", "\u958B\u59CB\u4F4D\u7F6E", "0").option("--limit <limit>", "\u53D6\u5F97\u4EF6\u6570\uFF08\u6700\u5927100\uFF09", "50").option("--include-archived", "\u30A2\u30FC\u30AB\u30A4\u30D6\u6E08\u307F\u3082\u542B\u3081\u308B").option("--include-closed", "Closed / Merged\u3082\u542B\u3081\u308B").action(
52963
+ async (options) => {
52964
+ const input = {
52965
+ offset: Number(options.offset),
52966
+ limit: Number(options.limit),
52967
+ hideArchived: !options.includeArchived,
52968
+ hideClosedOrMerged: !options.includeClosed
52969
+ };
52970
+ const result = await callService(
52971
+ "pr.list",
52972
+ input,
52973
+ () => getRuntime().service.listPullRequests(input)
52974
+ );
52975
+ writeOutput(
52976
+ options,
52977
+ { ok: true, ...result },
52978
+ result.items.map(
52979
+ (item) => `${item.owner}/${item.repository}#${item.number} ${item.title}${item.archivedAt ? " [archived]" : ""}`
52980
+ ).join("\n") || "\u8A72\u5F53\u3059\u308BPull Request\u306F\u3042\u308A\u307E\u305B\u3093\u3002"
52981
+ );
52982
+ }
52983
+ );
52984
+ for (const [command, archived] of [
52985
+ ["archive", true],
52986
+ ["unarchive", false]
52987
+ ]) {
52988
+ pr.command(command).argument("<pull-request>", "\u767B\u9332\u6E08\u307FPR URL\u307E\u305F\u306F\u756A\u53F7").option("--json", "JSON\u3067\u51FA\u529B").action(async (reference, options) => {
52989
+ const pullRequest = await callService("pr.archive", { reference, archived }, () => {
52990
+ const service = getRuntime().service;
52991
+ return service.setPullRequestArchived(
52992
+ service.resolveStoredPullRequest(reference).id,
52993
+ archived
52994
+ );
52995
+ });
52996
+ writeOutput(
52997
+ options,
52998
+ { ok: true, pullRequest },
52999
+ archived ? "\u30A2\u30FC\u30AB\u30A4\u30D6\u3057\u307E\u3057\u305F\u3002" : "\u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u89E3\u9664\u3057\u307E\u3057\u305F\u3002"
53000
+ );
53001
+ });
53002
+ }
52909
53003
  pr.command("refresh").argument("<pull-request>", "\u767B\u9332\u6E08\u307FPR URL\u307E\u305F\u306F\u756A\u53F7").option("--json", "JSON\u3067\u51FA\u529B").action(async (reference, options) => {
52910
53004
  const result = await callService(
52911
53005
  "pr.refresh",