Files
shared/scripts/lib/log.mjs
jiantw83andClaude Sonnet 5 1030f9d403 feat(shared): 新增14個共用spec、models/todo工具與樣板產生器,收斂跨repo重複規範
依 todo.md 執行的規範治理專案:新增 spec-preflight 等 14 個共用規範(含
conventional-commit/pull-request/git-push/issue-read/todo-list/ask-user/
subagent/no-scratch-files/skill-invocation/script-path/action-scaffold/
node-src-layout/plugin-cli/model),擴充 spec-git-safety 與 spec-gitea(token
優先序、機密遮蔽、Wiki 頁名轉義規則);新增可執行 skill `models`(模型能力
查詢與標籤)與 `todo`(依指定模型產生/附加 todo.md);新增 plugin.meta.json
單一事實來源與 gen-plugin-files.mjs 樣板產生器,統一四個 repo 的 manifest/
README/AGENTS.md 並移除寫死的本機使用者路徑;新增 shared/scripts/lib 的
log/機密遮蔽三語言參考實作。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 06:02:30 +00:00

40 lines
1.9 KiB
JavaScript

#!/usr/bin/env node
// ==============================================================================
// 用途:時間戳與 log 格式的參考實作(Node/mjs 版)。對應 /jsc-shared:spec-time-log
// 規範:更新時間一律 Asia/Taipei、固定 yyyy/MM/dd HH:mm:ss;輸出訊息一律
// [時間][階段][等級]: 訊息、一行一則、走 stderr。本檔案不會被其他 repo
// 跨 repo 直接 import,純供其他 repo 的腳本對照複製或標註對應關係
// (等價邏輯抽自 persona/scripts/persona-lib.mjs 的 nowDisplay(),只取
// 時間與 log 兩個函式,不耦合該檔其他情緒/記憶邏輯)。
// 更新時間:2026/08/11 00:00:00
// 相依:Node.js 標準內建功能,無外部套件。
// ==============================================================================
const TAIPEI_OFFSET_MS = 8 * 60 * 60 * 1000;
/**
* 回傳 Asia/Taipei 時區的 yyyy/MM/dd HH:mm:ss 時間字串。
* @param {Date} date 基準時間,預設為呼叫當下。
* @returns {string}
*/
export function nowTaipei(date = new Date()) {
const shifted = new Date(Math.floor(date.getTime() / 1000) * 1000 + TAIPEI_OFFSET_MS);
const pad = (n) => String(n).padStart(2, "0");
return `${shifted.getUTCFullYear()}/${pad(shifted.getUTCMonth() + 1)}/${pad(shifted.getUTCDate())} ${pad(shifted.getUTCHours())}:${pad(shifted.getUTCMinutes())}:${pad(shifted.getUTCSeconds())}`;
}
/**
* 輸出統一格式訊息([時間][階段][等級]: 訊息,一行一則),一律走 stderr。
* @param {string} level INF/WRN/ERR/TRC/DBG。
* @param {string} message 訊息內容。
* @param {string} [stage] 階段名稱,選填;空字串則不輸出 [階段] 區塊。
*/
export function log(level, message, stage = "") {
const stamp = nowTaipei();
if (stage) {
console.error(`[${stamp}][${stage}][${level}]: ${message}`);
} else {
console.error(`[${stamp}][${level}]: ${message}`);
}
}