帮助开发者设计安全持久的配置与状态文件管理模式,兼顾默认值合并和崩溃恢复。
复制安装指令,让 AI 自动完成配置 · 推荐新手
请帮我安装 askskill 上的 "config-state-patterns" 技能: 1. 下载 https://raw.githubusercontent.com/microsoft/amplifier-bundle-skills/main/skills/config-state-patterns/SKILL.md 2. 保存为 ~/.claude/skills/config-state-patterns/SKILL.md 3. 装好后重载技能,告诉我可以用了
请为一个桌面应用设计配置与状态文件方案:要求区分 config、state、secrets 的文件位置;支持默认配置与用户配置合并;状态写入必须原子化,避免程序崩溃后文件损坏。请给出目录约定、数据结构示例和写入流程。
一套清晰的配置/状态/密钥存储规范,包含目录路径、合并规则与原子写入方案。
我正在开发一个 CLI 工具,请帮我制定配置持久化规范:需要安全默认值、用户覆盖配置、运行状态缓存,以及敏感令牌的单独存放方式。请说明哪些内容应该放在配置文件、状态文件和 secrets 文件中。
一份面向 CLI 的文件职责划分建议,明确不同数据类型的存放位置与原因。
请给我一个崩溃安全的状态文件写入方案,适用于本地应用:要求先写临时文件,再原子替换正式文件,并考虑并发写入、权限控制和恢复策略。最好附上伪代码。
一个可落地的原子写入流程说明,附带并发、权限与恢复处理建议。
Problem: Your tool has user-configurable settings (host, port, auth mode) and runtime state (which sessions are active, device heartbeats) that must persist across restarts and handle concurrent reads/writes safely.
Approach: Separate config from state. Use a defaults-merge-overlay pattern with known-keys-only filtering for settings. Use atomic writes (write-to-tmp-then-os.replace) for state. Use asyncio locks for concurrent access. Follow XDG-conventional paths.
Pattern proven in production across multiple Python CLI tools and web services.
The settings file might be from an older version (missing new keys) or a newer version (has keys we don't understand). The load_settings() pattern handles both:
def load_settings() -> dict:
result = copy.deepcopy(DEFAULT_SETTINGS) # start with ALL defaults
try:
text = SETTINGS_PATH.read_text()
data = json.loads(text)
for key in DEFAULT_SETTINGS: # only copy KNOWN keys
if key in data:
result[key] = data[key]
except (FileNotFoundError, json.JSONDecodeError):
pass # corrupt/missing = use defaults
return result
The critical detail: iteration is over DEFAULT_SETTINGS keys, not over the file's keys. Unknown keys in the file are silently ignored. This prevents config drift when a user downgrades or when settings are synced between versions.
The same principle applies when saving:
def save_settings(data: dict) -> None:
merged = copy.deepcopy(DEFAULT_SETTINGS)
for key in DEFAULT_SETTINGS:
if key in data:
merged[key] = data[key]
SETTINGS_PATH.parent.mkdir(parents=True, exist_ok=True)
SETTINGS_PATH.write_text(json.dumps(merged, indent=2) + "\n")
And on patch (partial update):
def patch_settings(patch: dict) -> dict:
current = load_settings()
for key in DEFAULT_SETTINGS:
if key in patch:
current[key] = patch[key]
os.replaceState files can be read by other processes at any time. A naive write_text() can produce a half-written file if the process crashes mid-write.
The simple pattern:
def save_state(state: dict) -> None:
STATE_DIR.mkdir(parents=True, exist_ok=True)
tmp = Path(str(STATE_PATH) + ".tmp")
tmp.write_text(json.dumps(state, indent=2))
os.replace(tmp, STATE_PATH) # atomic on POSIX
For extra safety (no predictable tmp path, proper cleanup on error), use tempfile.mkstemp:
def _write_instance(self, instance_id: str, data: dict) -> None:
path = self._instance_path(instance_id)
path.parent.mkdir(parents=True, exist_ok=True)
content = json.dumps(data, ensure_ascii=False, default=str)
fd, tmp_path = tempfile.mkstemp(dir=path.parent, suffix=".tmp")
try:
os.write(fd, content.encode("utf-8"))
os.close(fd)
Path(tmp_path).replace(path)
except BaseException:
with contextlib.suppress(OSError):
os.close(fd)
Path(tmp_path).unlink(missing_ok=True)
raise
When state is accessed from a poll loop and from API handlers simultaneously, a module-level asyncio lock serializes access:
state_lock: asyncio.Lock = asyncio.Lock()
async def read_state() -> dict:
async with state_lock:
return load_state()
async def write_state(state: dict) -> None:
async with state_lock:
save_state(state)
For threading contexts, use threading.Lock per instance with a defaultdict:
self._locks: defaultdict[str, threading.Lock] = defaultdict(threading.Lock)
# Usage — every mutation acquires the per-instance lock:
…
帮助你安全编排 Docker 容器任务,并搭建可复现的开发运行环境
帮助开发者构建含生命周期管理、WebSocket与SSE的 HTTP 服务模式
以资深工程师视角审视架构、遗留重构与工具选型,给出务实建议。
用多模型视觉能力分析图片内容、提取文字并回答图像相关问题。
帮助你调研、规划并并行执行大规模代码变更,让多个代理分别提交 PR。
帮助开发与运维设计兼顾本地顺畅和远程安全的认证与 TLS 接入方案。
帮助开发者设计易安装、易扩展且配置分层清晰的 CLI 工具模式。
提供基于文件系统的进程间通信模式,适合无消息队列的本地协作场景
用于初始化项目时检查并创建社区治理所需的标准仓库文件。
帮助解析、校验、合并、转换并比较多种格式的配置文件
帮助开发者新增、修改或审查 VS Code 配置策略,并生成平台相关产物。
帮助开发者快速搭建无状态 MCP 服务器骨架,支持水平扩展与免会话亲和部署。