@horizon_works/banto 0.9.0 → 0.9.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/gate_core.js +65 -4
- package/package.json +1 -1
- package/server.js +33 -4
package/gate_core.js
CHANGED
|
@@ -441,14 +441,51 @@ function stamp() {
|
|
|
441
441
|
const d = new Date(), p = (n) => String(n).padStart(2, '0');
|
|
442
442
|
return `${d.getFullYear()}-${p(d.getMonth()+1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`;
|
|
443
443
|
}
|
|
444
|
-
|
|
444
|
+
// ─────────────────────────────────────────────
|
|
445
|
+
// ★出所タグ(2026-09-01)
|
|
446
|
+
//
|
|
447
|
+
// 🚨★由来: 出す側の主から「主の発言・リンク・ファイルを、そのまま角かっこで書きたい」。
|
|
448
|
+
// ★これができると、AIどうしで渡したときに混乱が減る。
|
|
449
|
+
// ★出す側でも、重い書式にしたら45日で951行中1行しか付かなかった=**重いと付かない**。
|
|
450
|
+
// ★★出所そのものを角かっこに入れるだけ。分類しない。
|
|
451
|
+
//
|
|
452
|
+
// ★なぜ機械で締めるか=★裁量に残すと付かない(実測で45日ゼロだった)。
|
|
453
|
+
// ★ただし締めるのは**出口(settle)**だけ。★入口(remember)は促すだけで止めない。
|
|
454
|
+
const 出所の形 = [
|
|
455
|
+
/\[(推測|実測|未確認)\]/g,
|
|
456
|
+
/\[(https?:\/\/[^\]\s]+)\]/g,
|
|
457
|
+
/\[([^\]\s]*\.(?:md|js|mjs|ts|py|json|txt|sql|html|csv|docx?|xlsx?|pdf))\]/g,
|
|
458
|
+
/\[([^\]。、\s]{1,14}(?:さん|先生|様))\]/g,
|
|
459
|
+
];
|
|
460
|
+
|
|
461
|
+
function readSrc(text) {
|
|
462
|
+
const out = [];
|
|
463
|
+
for (const re of 出所の形) {
|
|
464
|
+
re.lastIndex = 0;
|
|
465
|
+
let m;
|
|
466
|
+
while ((m = re.exec(String(text))) !== null) if (out.indexOf(m[1]) === -1) out.push(m[1]);
|
|
467
|
+
}
|
|
468
|
+
return out;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/** ★裏が取れる出所を持っているか(`[推測]` だけ、は持っていない) */
|
|
472
|
+
function 裏が取れる(text) {
|
|
473
|
+
const v = readSrc(text);
|
|
474
|
+
for (let i = 0; i < v.length; i++) if (v[i] !== '推測' && v[i] !== '未確認') return true;
|
|
475
|
+
return false;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
function remember(text, tag, sig, src) {
|
|
445
479
|
if (logOwner()) return kitNotice('retain.js add "<本文>" --score 0.5 --tag failure --sig <型キー>');
|
|
446
480
|
const t = String(text || '').trim();
|
|
447
481
|
if (!t) throw new Error('記録する内容がありません');
|
|
448
482
|
const f = logPath();
|
|
449
483
|
const oneLine = t.split(String.fromCharCode(10)).join(' ').split(String.fromCharCode(13)).join(' ');
|
|
484
|
+
// ★出所タグ。src で足せる(★本文に直接 [推測] などと書いてもよい。拾う)
|
|
485
|
+
const 出所 = String(src || '').trim();
|
|
486
|
+
const 本文 = 出所 ? (oneLine + ' [' + 出所.replace(/[\[\]]/g, '') + ']') : oneLine;
|
|
450
487
|
const line = '- [ ] ' + stamp() + ' | ' + (tag || 'note')
|
|
451
|
-
+ (sig ? ' 〔' + sig + '〕' : '') + ' | ' +
|
|
488
|
+
+ (sig ? ' 〔' + sig + '〕' : '') + ' | ' + 本文 + String.fromCharCode(10);
|
|
452
489
|
if (!fs.existsSync(f)) {
|
|
453
490
|
fs.writeFileSync(f,
|
|
454
491
|
'# 気づいたことの下書き帳' + String.fromCharCode(10) + String.fromCharCode(10)
|
|
@@ -477,7 +514,15 @@ function remember(text, tag, sig) {
|
|
|
477
514
|
+ '★同じ型は、他の方でもよく出ます。'
|
|
478
515
|
: null;
|
|
479
516
|
|
|
517
|
+
const 出所の状態 = readSrc(本文);
|
|
518
|
+
const 出所の声 = !出所の状態.length
|
|
519
|
+
? '★出所がありません。★settle(片づけ)のときに止まります。src に [推測] [実測] [◯◯さん] [URL] のどれかを。'
|
|
520
|
+
: (!裏が取れる(本文)
|
|
521
|
+
? '★出所が「' + 出所の状態.join(',') + '」だけ=裏が取れません。確かめてから [実測] へ書き換えてください。'
|
|
522
|
+
: null);
|
|
523
|
+
|
|
480
524
|
return { saved_to: f, pending: open.length, sig: sig || null, sig_count: sigCount,
|
|
525
|
+
出所: 出所の状態.length ? 出所の状態 : null, 出所について: 出所の声,
|
|
481
526
|
hint: hint, '★次の一手': 声かけ || undefined };
|
|
482
527
|
}
|
|
483
528
|
const ENTRY_RE = new RegExp('^- \\[( |x)\\] (\\d{4}-\\d{2}-\\d{2}) (\\d{2}:\\d{2}) \\| (.*)$');
|
|
@@ -584,15 +629,25 @@ function review(record) {
|
|
|
584
629
|
* ids … 片づけた記録の番号(recall / review が返す id)
|
|
585
630
|
* ruled_to … ルールや手順にしたときの置き場所(sig と一緒に指定)
|
|
586
631
|
*/
|
|
587
|
-
function settle(ids, sig, ruledTo) {
|
|
632
|
+
function settle(ids, sig, ruledTo, force) {
|
|
588
633
|
if (logOwner()) return kitNotice('retain.js promote <行番号...>');
|
|
589
634
|
const { file, lines, entries } = readLog();
|
|
590
635
|
if (!fs.existsSync(file)) throw new Error('まだ記録がありません');
|
|
591
636
|
let closed = 0;
|
|
637
|
+
const 止めた = [];
|
|
592
638
|
for (const id of (ids || [])) {
|
|
593
639
|
const i = Number(id) - 1;
|
|
594
640
|
if (i < 0 || i >= lines.length) continue;
|
|
595
|
-
if (lines[i].indexOf('- [ ] ')
|
|
641
|
+
if (lines[i].indexOf('- [ ] ') !== 0) continue;
|
|
642
|
+
// 🚨★**出所の関所はここ**(2026-09-01)。★裏の取れない記録を、片づけ済みにしない。
|
|
643
|
+
// ★入口(remember)は締めない。★締めるのは出口だけ。逃げ道は force。
|
|
644
|
+
if (!force && !裏が取れる(lines[i])) {
|
|
645
|
+
止めた.push({ id: Number(id), 出所: readSrc(lines[i]),
|
|
646
|
+
なぜ: readSrc(lines[i]).length ? '出所が「推測」だけです' : '出所がありません' });
|
|
647
|
+
continue;
|
|
648
|
+
}
|
|
649
|
+
lines[i] = lines[i].replace('- [ ] ', '- [x] ');
|
|
650
|
+
closed++;
|
|
596
651
|
}
|
|
597
652
|
|
|
598
653
|
let ruledLine = null;
|
|
@@ -619,6 +674,12 @@ function settle(ids, sig, ruledTo) {
|
|
|
619
674
|
return {
|
|
620
675
|
saved_to: file,
|
|
621
676
|
片づけた件数: closed,
|
|
677
|
+
'★止めた件数': 止めた.length || undefined,
|
|
678
|
+
'★止めた理由': 止めた.length ? 止めた : undefined,
|
|
679
|
+
'★止まったときは': 止めた.length
|
|
680
|
+
? '出所を確かめて本文へ [実測] か [◯◯さん] か [URL] を足してから、もう一度 settle してください。'
|
|
681
|
+
+ '★どうしても通すなら force: true(★使ったことは残ります)'
|
|
682
|
+
: undefined,
|
|
622
683
|
ルールにした印: ruledLine,
|
|
623
684
|
残りの未処理: after.entries.filter((e) => !e.done).length,
|
|
624
685
|
note: ruledLine
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -256,13 +256,16 @@ const TOOLS = [
|
|
|
256
256
|
name: 'remember',
|
|
257
257
|
description:
|
|
258
258
|
'気づいたこと・失敗・学びを1行だけ記録します。★会話を止めずに使ってください(記録は促しであって関所ではありません)。' +
|
|
259
|
-
'同じ型キーが3件たまったら「ルールか手順に落とす番」だと返します。★溜めるのが目的ではありません。'
|
|
259
|
+
'同じ型キーが3件たまったら「ルールか手順に落とす番」だと返します。★溜めるのが目的ではありません。' +
|
|
260
|
+
'★出所(src)を必ず添えてください。★見たことと考えたことを混ぜないためです。',
|
|
260
261
|
inputSchema: {
|
|
261
262
|
type: 'object',
|
|
262
263
|
properties: {
|
|
263
264
|
text: { type: 'string', description: '何が起きたか・なぜか(1行)' },
|
|
264
265
|
tag: { type: 'string', description: 'failure(失敗)/insight(発見)/value(価値観)/fact(事実)' },
|
|
265
266
|
sig: { type: 'string', description: '型キー。同じ失敗を数えるための短い名前(例: 確かめる前に断定した)' },
|
|
267
|
+
src: { type: 'string', description: '★出所。[推測]/[実測]/[◯◯さん]/URL/ファイル名のどれか。'
|
|
268
|
+
+ '★これが無いと settle で止まります。迷ったら 推測。' },
|
|
266
269
|
},
|
|
267
270
|
required: ['text'],
|
|
268
271
|
},
|
|
@@ -308,6 +311,7 @@ const TOOLS = [
|
|
|
308
311
|
ids: { type: 'array', items: { type: 'number' }, description: '片づけた記録の番号' },
|
|
309
312
|
sig: { type: 'string', description: 'ルールにした型キー' },
|
|
310
313
|
ruled_to: { type: 'string', description: 'どこに書いたか' },
|
|
314
|
+
force: { type: 'boolean', description: '★出所が無くても閉じる(★使ったことは残ります)' },
|
|
311
315
|
},
|
|
312
316
|
},
|
|
313
317
|
},
|
|
@@ -1637,7 +1641,7 @@ function callTool(name, args) {
|
|
|
1637
1641
|
}
|
|
1638
1642
|
|
|
1639
1643
|
if (name === 'remember') {
|
|
1640
|
-
return FREE.remember(args && args.text, args && args.tag, args && args.sig);
|
|
1644
|
+
return FREE.remember(args && args.text, args && args.tag, args && args.sig, args && args.src);
|
|
1641
1645
|
}
|
|
1642
1646
|
|
|
1643
1647
|
if (name === 'recall') {
|
|
@@ -1675,7 +1679,7 @@ function callTool(name, args) {
|
|
|
1675
1679
|
}
|
|
1676
1680
|
|
|
1677
1681
|
if (name === 'settle') {
|
|
1678
|
-
return FREE.settle(args && args.ids, args && args.sig, args && args.ruled_to);
|
|
1682
|
+
return FREE.settle(args && args.ids, args && args.sig, args && args.ruled_to, args && args.force);
|
|
1679
1683
|
}
|
|
1680
1684
|
|
|
1681
1685
|
if (name === 'checkup') {
|
|
@@ -1929,7 +1933,20 @@ let LICENSE_STATE = { allowed: true, status: 'unconfigured', message: '', daysLe
|
|
|
1929
1933
|
// ここで送るのは型キーの名前と件数だけ(組み立ては client 側の buildStats に閉じてある)。
|
|
1930
1934
|
// ★送れなくても、何も止めない。
|
|
1931
1935
|
if (LICENSE_STATE.allowed && LIC.isSharing && LIC.isSharing()) {
|
|
1932
|
-
|
|
1936
|
+
// 🚨★失敗を握りつぶさない(2026-09-01)。
|
|
1937
|
+
// ★ここが `catch (_) {}` だったので、「同意しているのに何も届かない」を
|
|
1938
|
+
// ★こちらもお手元も**一度も知ることができなかった**。
|
|
1939
|
+
// ★止めはしない。★手元の控えに1行だけ残す(`checkup` で読める)。
|
|
1940
|
+
try {
|
|
1941
|
+
await LIC.reportStats(VERSION, FREE.review(false));
|
|
1942
|
+
try { fs.writeFileSync(path.join(CORE_HOME, '.stats_last.json'),
|
|
1943
|
+
JSON.stringify({ ok: true, at: new Date().toISOString() }, null, 2), 'utf8'); } catch (_) {}
|
|
1944
|
+
} catch (e) {
|
|
1945
|
+
try { fs.mkdirSync(CORE_HOME, { recursive: true }); } catch (_) {}
|
|
1946
|
+
try { fs.writeFileSync(path.join(CORE_HOME, '.stats_last.json'),
|
|
1947
|
+
JSON.stringify({ ok: false, at: new Date().toISOString(),
|
|
1948
|
+
why: String(e && e.message || e).slice(0, 200) }, null, 2), 'utf8'); } catch (_) {}
|
|
1949
|
+
}
|
|
1933
1950
|
}
|
|
1934
1951
|
|
|
1935
1952
|
// ★核の新しい版が出ていないかを、1日1回だけ見にいく(★版だけ。中身は取らない)
|
|
@@ -1937,6 +1954,18 @@ let LICENSE_STATE = { allowed: true, status: 'unconfigured', message: '', daysLe
|
|
|
1937
1954
|
// ★★黙って上書きしない。★出るのは「取ってきますか」まで。
|
|
1938
1955
|
if (LICENSE_STATE.allowed) {
|
|
1939
1956
|
try { await 核の版を取りにいく(); } catch (_) {}
|
|
1957
|
+
|
|
1958
|
+
// 🚨★**一度も入っていないときだけ、自動で取る**(2026-09-01)
|
|
1959
|
+
// ★由来=お渡しした方が4日つないで、記録が0件だった。
|
|
1960
|
+
// 調べたら **核そのものが入っていなかった**(`checkup` に「このフォルダには無い」)。
|
|
1961
|
+
// ★`sync_core` は**相手のAIが自分で呼ばないと動かない**作りだった。
|
|
1962
|
+
// → tooling-check.md §1手順5「裁量の出番を残した関所は、経路が増えた瞬間に漏れる」
|
|
1963
|
+
// ★★上の「黙って上書きしない」は**更新の話**。★ここは**初回**で、上書きするものが無い。
|
|
1964
|
+
// だから設計と衝突しない。★更新は今までどおり、お知らせだけ。
|
|
1965
|
+
try {
|
|
1966
|
+
const 初めて = !fs.existsSync(path.join(CORE_HOME, 'instructions.md'));
|
|
1967
|
+
if (初めて) await syncCore();
|
|
1968
|
+
} catch (_) { /* ★取れなくても何も止めない */ }
|
|
1940
1969
|
}
|
|
1941
1970
|
} catch (_) {
|
|
1942
1971
|
// license モジュールが無い構成でも動く
|