@helpfeel/cosense-cli 1.15.0 → 1.16.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/README.md +4 -0
- package/package.json +5 -5
- package/src/commands/browsePage.ts +10 -5
- package/src/commands/submitEdit.ts +1 -1
- package/src/lib/encodeTitle.ts +8 -11
package/README.md
CHANGED
|
@@ -45,4 +45,8 @@ cosense --help
|
|
|
45
45
|
|
|
46
46
|
- install [direnv](https://direnv.net/)
|
|
47
47
|
- run `npm install`
|
|
48
|
+
- install [Codex CLI](https://github.com/openai/codex) and run `codex login`
|
|
49
|
+
- modelは `gpt-5.6-sol`、reasoning effortは `high` 以上を推奨
|
|
48
50
|
- run `claude` or `codex`
|
|
51
|
+
|
|
52
|
+
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.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"description": "Cosense (旧Scrapbox) のページを読み・調べ・編集するAgent Skillのハーネス",
|
|
5
5
|
"homepage": "https://github.com/helpfeel/cosense-cli",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
"format": "oxfmt"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"tsx": "4.23.
|
|
27
|
+
"tsx": "4.23.15"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@types/node": "24.13.
|
|
30
|
+
"@types/node": "24.13.6",
|
|
31
31
|
"npm-run-all": "4.1.5",
|
|
32
|
-
"oxfmt": "0.
|
|
33
|
-
"oxlint": "1.
|
|
32
|
+
"oxfmt": "0.70.0",
|
|
33
|
+
"oxlint": "1.85.0",
|
|
34
34
|
"typescript": "7.0.2"
|
|
35
35
|
},
|
|
36
36
|
"engines": {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { enrichTimestampsOf } from '../lib/enrichTimestamps.ts';
|
|
2
|
+
import { encodeTitleForUrl } from '../lib/encodeTitle.ts';
|
|
2
3
|
import { applyFileMarkup, fetchFileMarkups } from '../lib/fileMarkup.ts';
|
|
3
4
|
import { renderLiterateDatabase } from '../lib/literateDatabase.ts';
|
|
4
5
|
import { parsePageUrl } from '../lib/parseUrl.ts';
|
|
@@ -34,9 +35,10 @@ Usage:
|
|
|
34
35
|
# <title>
|
|
35
36
|
|
|
36
37
|
## メタデータ
|
|
37
|
-
タイトル / pageId / commitId / 作成日時 / 最終更新日時 / 最終アクセス日時 /
|
|
38
|
+
タイトル / URL / pageId / commitId / 作成日時 / 最終更新日時 / 最終アクセス日時 /
|
|
38
39
|
被リンク数 / pageRank / views / snapshot / 行数 / 文字数 / 作成者 / 最終更新者 /
|
|
39
40
|
関わったユーザー
|
|
41
|
+
URL はタイトルをパーセントエンコードしたページURL
|
|
40
42
|
pageId はページの不変ID、commitId は閲覧時点の最新コミット。共同編集中に
|
|
41
43
|
ページを見失ったら、これらを browsePageChanges に渡して変更(リネーム含む)を辿れる
|
|
42
44
|
|
|
@@ -90,8 +92,8 @@ Usage:
|
|
|
90
92
|
## 1 hop link(表に載っていないページ) に出力する
|
|
91
93
|
|
|
92
94
|
persistent: false の時:
|
|
93
|
-
|
|
94
|
-
本文(テンプレート)と Related Pages を出力する
|
|
95
|
+
アイコン・テロメア・Infoboxは省略し、メタデータはURLだけを出力する。
|
|
96
|
+
(このページはまだ作成されていません) と 本文(テンプレート)と Related Pages を出力する
|
|
95
97
|
|
|
96
98
|
URLに #<lineId> fragmentが指定された時:
|
|
97
99
|
タイトル直後に判定結果を1行出力する。
|
|
@@ -206,9 +208,10 @@ const buildTelomere = (lines: PageLine[]): TelomereEntry[] => {
|
|
|
206
208
|
return [...byUser.values()].sort((a, b) => b.lineCount - a.lineCount);
|
|
207
209
|
};
|
|
208
210
|
|
|
209
|
-
const renderMetadata = (page: PageData): string => {
|
|
211
|
+
const renderMetadata = (page: PageData, pageUrl: string): string => {
|
|
210
212
|
const items: string[] = [];
|
|
211
213
|
if (typeof page.title === 'string') items.push(`- タイトル: ${page.title}`);
|
|
214
|
+
items.push(`- URL: ${pageUrl}`);
|
|
212
215
|
if (typeof page.id === 'string') items.push(`- pageId: ${page.id}`);
|
|
213
216
|
if (typeof page.commitId === 'string') {
|
|
214
217
|
items.push(`- commitId: ${page.commitId}`);
|
|
@@ -358,10 +361,12 @@ export const browsePage = async (args: string[]): Promise<void> => {
|
|
|
358
361
|
|
|
359
362
|
const title = page.title ?? '';
|
|
360
363
|
const persistent = page.persistent !== false;
|
|
364
|
+
const pageUrl = `${origin}/${projectName}/${encodeTitleForUrl(title)}`;
|
|
361
365
|
const sections: string[] = [`# ${title}`];
|
|
362
366
|
|
|
363
367
|
if (!persistent) {
|
|
364
368
|
sections.push('(このページはまだ作成されていません)');
|
|
369
|
+
sections.push(`## メタデータ\n\n- URL: ${pageUrl}`);
|
|
365
370
|
const { body } = renderBody(page.lines ?? [], null, new Map());
|
|
366
371
|
sections.push(`## 本文(テンプレート)\n\n${body}`);
|
|
367
372
|
const related = renderRelatedPages(hopValue, page);
|
|
@@ -409,7 +414,7 @@ export const browsePage = async (args: string[]): Promise<void> => {
|
|
|
409
414
|
]);
|
|
410
415
|
enrichPageUsers(page, userMap);
|
|
411
416
|
|
|
412
|
-
sections.push(renderMetadata(page));
|
|
417
|
+
sections.push(renderMetadata(page, pageUrl));
|
|
413
418
|
|
|
414
419
|
const iconsSection = renderHumanIcons(page.icons, userMap);
|
|
415
420
|
if (iconsSection) sections.push(iconsSection);
|
|
@@ -18,7 +18,7 @@ Usage:
|
|
|
18
18
|
戻り値(plain text):
|
|
19
19
|
commitId: <生成されたcommitのID>
|
|
20
20
|
title: <実際に書き込まれたpage title>
|
|
21
|
-
url: <作成または更新された page の URL
|
|
21
|
+
url: <作成または更新された page の URL。タイトルはパーセントエンコード済み>
|
|
22
22
|
|
|
23
23
|
url はサーバーが返す title から再構築される。 同名ページが既に存在する場合、 サーバーは
|
|
24
24
|
タイトルに auto-suffix を付ける (新規作成でも既存ページのタイトル変更でも起きる)。
|
package/src/lib/encodeTitle.ts
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// cosense server の route match (`/:projectName/:title`, `:title=[^/]+`) を満たすため
|
|
4
|
-
// title 内の `/` は `%2F` 必須。 URL syntax を破壊する `%` `?` `#` も percent-encode する。
|
|
5
|
-
// space は cosense convention で `_` に置換。
|
|
1
|
+
// 非ASCIIを生で残すと、`%2F`等と混ざったURLをmacOSのターミナルが開く時に`%`が再エンコードされ、別のページに飛ぶ
|
|
2
|
+
// 半角スペースはCosenseの慣習で`_`に置換する
|
|
6
3
|
export const encodeTitleForUrl = (title: string): string => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
.
|
|
12
|
-
|
|
4
|
+
// 孤立サロゲートが残っているとencodeURIComponentが例外を投げる
|
|
5
|
+
return encodeURIComponent(title.toWellFormed().replace(/ /g, '_')).replace(
|
|
6
|
+
// encodeURIComponentが残すRFC 3986の予約文字。括弧はMarkdownリンクのリンク先を、`'`はshellのクォートを壊しうる
|
|
7
|
+
/[!'()*]/g,
|
|
8
|
+
c => `%${c.charCodeAt(0).toString(16).toUpperCase()}`
|
|
9
|
+
);
|
|
13
10
|
};
|