@horizon_works/banto 0.8.8 → 0.9.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/license/client.js +56 -11
- package/package.json +1 -1
- package/server.js +8 -2
package/license/client.js
CHANGED
|
@@ -193,6 +193,9 @@ async function check(version) {
|
|
|
193
193
|
status: r.status || 'unknown',
|
|
194
194
|
daysLeft: typeof r.days_left === 'number' ? r.days_left : null,
|
|
195
195
|
plan: r.plan || null, expiresAt: r.expires_at || null,
|
|
196
|
+
// ★台帳の「統計を送ってよい」印を控える(★isSharing の③が読む)
|
|
197
|
+
// ★これは**入れる側**だけに効く。★止めるのは常に手元の share.json
|
|
198
|
+
stats_opt_in: r.stats_opt_in === true,
|
|
196
199
|
lastOkAt: r.status === 'active' ? now : (cache && cache.lastOkAt) || null,
|
|
197
200
|
};
|
|
198
201
|
writeCache(next);
|
|
@@ -244,17 +247,34 @@ const HOME = process.env.BANTO_HOME || path.join(require('os').homedir(), '.bant
|
|
|
244
247
|
const STATS_CACHE = path.join(HOME, '.stats.json');
|
|
245
248
|
|
|
246
249
|
/**
|
|
247
|
-
*
|
|
250
|
+
* 送ることに同意しているか
|
|
248
251
|
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
*
|
|
252
|
+
* ★強さの順(2026-08-29)
|
|
253
|
+
* ① 手元で「止めて」と言われていたら → ★**必ず止まる**(本人の意思がいちばん強い)
|
|
254
|
+
* ② 手元で「送る」と言われていたら → 送る
|
|
255
|
+
* ③ 手元に何も無ければ → ★**台帳の `stats_opt_in`** を見る
|
|
256
|
+
* ④ どれも無ければ → ★送らない(既定オフ。★書面のとおり)
|
|
257
|
+
*
|
|
258
|
+
* 🚨★③を足した理由(2026-08-29)
|
|
259
|
+
* ★`stats_opt_in` の列は 2026-08-21 から在ったのに、**誰も読んでいなかった**
|
|
260
|
+
* (→ tooling-check.md「列を作った日に、読む側を書く」)。
|
|
261
|
+
* ★身内へお渡しした鍵など、**こちらで入れたい**場面がある。
|
|
262
|
+
* ★★ただし**切る力は台帳に持たせない**。★止めるのは常に本人。
|
|
263
|
+
* ★誰がいつ入れたかは `stats_opt_in_at` に残る(★あとから説明できる)。
|
|
254
264
|
*/
|
|
255
265
|
function isSharing() {
|
|
256
|
-
|
|
257
|
-
|
|
266
|
+
// ① ② 手元に書いてあれば、それが最優先
|
|
267
|
+
try {
|
|
268
|
+
const j = JSON.parse(fs.readFileSync(path.join(HOME, 'share.json'), 'utf8'));
|
|
269
|
+
if (typeof j.stats === 'boolean') return j.stats;
|
|
270
|
+
} catch (_) {}
|
|
271
|
+
// ③ 台帳の印(★最後に確かめたときの結果を控えから読む。通信しない)
|
|
272
|
+
try {
|
|
273
|
+
const c = readCache();
|
|
274
|
+
if (c && c.stats_opt_in === true) return true;
|
|
275
|
+
} catch (_) {}
|
|
276
|
+
// ④ 既定は送らない
|
|
277
|
+
return false;
|
|
258
278
|
}
|
|
259
279
|
|
|
260
280
|
/** 同意を切り替える(★人が明示的に呼んだときだけ) */
|
|
@@ -288,6 +308,28 @@ function buildStats(review) {
|
|
|
288
308
|
* 送る(★1日1回)
|
|
289
309
|
* @returns {Promise<{sent:boolean, reason:string, count:number}>}
|
|
290
310
|
*/
|
|
311
|
+
/**
|
|
312
|
+
* ★記録の数え方だけを取り出す(2026-08-30)
|
|
313
|
+
*
|
|
314
|
+
* ★送るのは**数だけ**。★何を書いたかは入らない。
|
|
315
|
+
* ★書面(banto-monitor v4.0)に先に書いてから足した。
|
|
316
|
+
*
|
|
317
|
+
* ★なぜ要るか=「型が無い」と「型を付けていない」は別。
|
|
318
|
+
* ★型が付いていないと、**3件で鳴る仕組みが一度も動かない**。
|
|
319
|
+
*/
|
|
320
|
+
function buildCounts(review) {
|
|
321
|
+
if (!review) return null;
|
|
322
|
+
const n = (v) => (typeof v === 'number' ? v : null);
|
|
323
|
+
const c = {
|
|
324
|
+
total: n(review['総数'] ?? review.total),
|
|
325
|
+
no_sig: n(review['型を付けていないもの'] ?? review.no_sig),
|
|
326
|
+
pending: n(review['未処理'] ?? review.pending),
|
|
327
|
+
};
|
|
328
|
+
// ★1つも数えられていなければ送らない
|
|
329
|
+
if (c.total === null && c.no_sig === null && c.pending === null) return null;
|
|
330
|
+
return c;
|
|
331
|
+
}
|
|
332
|
+
|
|
291
333
|
async function reportStats(version, review) {
|
|
292
334
|
const { key, url, anonKey } = config();
|
|
293
335
|
if (!key || !url || !anonKey) return { sent: false, reason: 'unconfigured', count: 0 };
|
|
@@ -295,7 +337,9 @@ async function reportStats(version, review) {
|
|
|
295
337
|
if (!isSharing()) return { sent: false, reason: 'opted-out', count: 0 };
|
|
296
338
|
|
|
297
339
|
const stats = buildStats(review);
|
|
298
|
-
|
|
340
|
+
const counts = buildCounts(review);
|
|
341
|
+
// ★型が1つも無くても、数え方があれば送る(★「型を付けていない」を知らせたい)
|
|
342
|
+
if (!stats.length && !counts) return { sent: false, reason: 'nothing', count: 0 };
|
|
299
343
|
|
|
300
344
|
// ★1日1回(同じ日に何度起動しても増えない)
|
|
301
345
|
const today = new Date().toISOString().slice(0, 10);
|
|
@@ -306,7 +350,8 @@ async function reportStats(version, review) {
|
|
|
306
350
|
const keyHash = crypto.createHash('sha256').update(key).digest('hex');
|
|
307
351
|
const rpc = url.replace(/verify_license\/?$/, 'report_stats');
|
|
308
352
|
try {
|
|
309
|
-
await post(rpc, { p_key_hash: keyHash, p_version: version || null,
|
|
353
|
+
await post(rpc, { p_key_hash: keyHash, p_version: version || null,
|
|
354
|
+
p_stats: stats, p_counts: counts }, anonKey);
|
|
310
355
|
try { fs.writeFileSync(STATS_CACHE, JSON.stringify({ on: today, count: stats.length }, null, 2)); } catch (_) {}
|
|
311
356
|
return { sent: true, reason: 'ok', count: stats.length };
|
|
312
357
|
} catch (e) {
|
|
@@ -315,4 +360,4 @@ async function reportStats(version, review) {
|
|
|
315
360
|
}
|
|
316
361
|
}
|
|
317
362
|
|
|
318
|
-
module.exports = { check, reportStats, buildStats, isSharing, setSharing , peek, config};
|
|
363
|
+
module.exports = { check, reportStats, buildStats, isSharing, setSharing , peek, config, buildCounts};
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -1654,13 +1654,19 @@ function callTool(name, args) {
|
|
|
1654
1654
|
if (!LIC || !LIC.setSharing) return { error: 'この構成では使えません(鍵の口がありません)' };
|
|
1655
1655
|
if (args && typeof args.on === 'boolean') LIC.setSharing(args.on);
|
|
1656
1656
|
const on = LIC.isSharing();
|
|
1657
|
-
const
|
|
1657
|
+
const 見た = FREE.review(false);
|
|
1658
|
+
const 送られるもの = LIC.buildStats(見た);
|
|
1659
|
+
// ★記録の数え方も見せる(★書面に「そのとき送られる中身がそのまま出る」と書いてある)
|
|
1660
|
+
const 数え方 = LIC.buildCounts ? LIC.buildCounts(見た) : null;
|
|
1658
1661
|
return {
|
|
1659
1662
|
いまの設定: on ? '送ります' : '★送りません(既定)',
|
|
1660
|
-
送るもの: '
|
|
1663
|
+
送るもの: '型キーの名前と件数、そして記録の数え方(★数だけ)',
|
|
1661
1664
|
送らないもの: ['記録の本文', '検査した文章', '顧客名・事業所名', 'ファイルの中身', 'パソコンの中の何か'],
|
|
1662
1665
|
回数: '1日に1回まで',
|
|
1663
1666
|
'★いま送られる中身': 送られるもの.length ? 送られるもの : '(まだ型キーが付いた記録がありません)',
|
|
1667
|
+
'★いま送られる数え方': 数え方
|
|
1668
|
+
? { 記録がぜんぶで: 数え方.total, うち型を付けていない: 数え方.no_sig, まだ片づけていない: 数え方.pending }
|
|
1669
|
+
: '(まだ記録がありません)',
|
|
1664
1670
|
切り替え方: 'share_stats を on: true / false で呼んでください。いつでも変えられます',
|
|
1665
1671
|
note: on
|
|
1666
1672
|
? '★これは、同じ失敗が他の方でも起きているかを見て、助言に使うためのものです。中身は読めません。'
|