@helpfeel/cosense-cli 1.16.1 → 1.16.2

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/README.md CHANGED
@@ -46,7 +46,6 @@ cosense --help
46
46
  - install [direnv](https://direnv.net/)
47
47
  - run `npm install`
48
48
  - install [Codex CLI](https://github.com/openai/codex) and run `codex login`
49
- - modelは `gpt-5.6-sol`、reasoning effortは `high` 以上を推奨
50
49
  - run `claude` or `codex`
51
50
 
52
51
  Claude Codeでこのディレクトリをtrustすると、開発フローで使うpluginが `.claude/settings.json` によりインストールされる。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@helpfeel/cosense-cli",
3
- "version": "1.16.1",
3
+ "version": "1.16.2",
4
4
  "description": "Cosense (旧Scrapbox) のページを読み・調べ・編集するAgent Skillのハーネス",
5
5
  "homepage": "https://github.com/helpfeel/cosense-cli",
6
6
  "license": "MIT",
@@ -27,10 +27,10 @@
27
27
  "tsx": "4.23.15"
28
28
  },
29
29
  "devDependencies": {
30
- "@types/node": "24.13.6",
30
+ "@types/node": "24.19.1",
31
31
  "npm-run-all": "4.1.5",
32
- "oxfmt": "0.70.0",
33
- "oxlint": "1.85.0",
32
+ "oxfmt": "0.71.0",
33
+ "oxlint": "1.86.0",
34
34
  "typescript": "7.0.2"
35
35
  },
36
36
  "engines": {
@@ -30,9 +30,6 @@ Usage:
30
30
  HTTPエラー:
31
31
  401/403: 認証・権限が無い。private projectのファイルはproject member権限が必要
32
32
  404: fileIdに対応するファイルが存在しない
33
-
34
- 注記:
35
- 動画ファイルはサーバー側の制限により取得できない場合がある
36
33
  `;
37
34
 
38
35
  interface ParsedArgs {
@@ -76,8 +76,8 @@ const parseArgs = (args: string[]): ParsedArgs => {
76
76
  };
77
77
  };
78
78
 
79
- // request.tsのHttpErrorは401/403でcosense loginを案内するが、GCSのsigned URLへの
80
- // PUT失敗にログイン案内は誤誘導なので専用のエラーメッセージを組み立てる
79
+ // request.tsのHttpErrorは401/403でcosense loginか権限の確認を案内するが、GCSのsigned URLへの
80
+ // PUT失敗にはどちらも誤誘導なので専用のエラーメッセージを組み立てる
81
81
  const uploadToSignedUrl = async (
82
82
  url: string,
83
83
  body: Uint8Array,
@@ -5,6 +5,11 @@ import { Readable } from 'node:stream';
5
5
  import { pipeline } from 'node:stream/promises';
6
6
  import type { Credential } from './settings.ts';
7
7
 
8
+ const describeCredentialDenied = (credential: Credential): string =>
9
+ credential.type === 'serviceAccount'
10
+ ? 'Service Account key was sent, but the server denied access. Check that the key belongs to the project of the target resource and that this operation is allowed.'
11
+ : 'Personal Access Token was sent, but the server denied access. Check that the account has permission for the target resource and this operation.';
12
+
8
13
  export class HttpError extends Error {
9
14
  readonly status: number;
10
15
  readonly statusText: string;
@@ -16,9 +21,13 @@ export class HttpError extends Error {
16
21
  statusText: string;
17
22
  url: string;
18
23
  body: string;
24
+ credential?: Credential;
19
25
  }) {
20
26
  let message = `HTTP ${params.status} ${params.statusText}\n${params.url}\n${params.body.slice(0, 500)}`;
21
- if (params.status === 401 || params.status === 403) {
27
+ if (params.status === 403 && params.credential) {
28
+ // credential付きの403はtokenの入れ直しでは直らないので、login案内ではなく権限の確認を促す
29
+ message += `\n\n${describeCredentialDenied(params.credential)}`;
30
+ } else if (params.status === 401 || params.status === 403) {
22
31
  let origin: string | undefined;
23
32
  try {
24
33
  origin = new URL(params.url).origin;
@@ -76,7 +85,8 @@ export const requestJson = async (
76
85
  status: res.status,
77
86
  statusText: res.statusText,
78
87
  url,
79
- body
88
+ body,
89
+ credential: options?.credential
80
90
  });
81
91
  }
82
92
  return res.json();
@@ -129,7 +139,8 @@ export const downloadToFile = async (
129
139
  status: res.status,
130
140
  statusText: res.statusText,
131
141
  url,
132
- body
142
+ body,
143
+ credential: options?.credential
133
144
  });
134
145
  }
135
146
  if (!res.body) {