@x-otto/coding 0.0.1-alpha.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.
@@ -0,0 +1,2 @@
1
+ import{join as e}from"node:path";import{readdir as t,stat as n,unlink as r}from"node:fs/promises";function i(e){let t=e.indexOf(`.`);if(!(t<=0))try{return decodeURIComponent(e.slice(0,t))}catch{return}}async function a(a){let o=a.mode??`delete`,s={scanned:0,orphans:0,deleted:0,reclaimedBytes:0};if(o===`off`)return s;for(let c of a.dirs){let l;try{l=await t(c)}catch{continue}for(let t of l){let l=i(t);if(!l||(s.scanned++,a.liveSessionIds.has(l)))continue;s.orphans++;let u=e(c,t),d=0;try{d=(await n(u)).size}catch{}if(o===`dry-run`){a.logger.info({path:u,size:d},`Orphan trace file (dry-run, not deleted)`);continue}try{await r(u),s.deleted++,s.reclaimedBytes+=d}catch(e){a.logger.warn({path:u,err:e instanceof Error?e.message:String(e)},`Failed to delete orphan trace file`)}}}return s.orphans>0&&a.logger.info({scanned:s.scanned,orphans:s.orphans,deleted:s.deleted,reclaimedMB:Math.round(s.reclaimedBytes/1e6),mode:o},`Orphan trace sweep completed`),s}export{a as sweepOrphanTraces};
2
+ //# sourceMappingURL=trace-orphan-sweeper-BdEIlLfB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-orphan-sweeper-BdEIlLfB.js","names":[],"sources":["../src/app/trace-orphan-sweeper.ts"],"sourcesContent":["/** Trace orphan sweeper: cleanup stale trace files from crashes. */\nimport { readdir, stat, unlink } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nimport type { Logger } from '@x-otto/shared'\n\nexport interface TraceOrphanSweepOptions {\n /** trace/checkpoint 等 append-log 目录(如 ~/.otto/sessions/trace)。 */\n dirs: string[]\n /** 已知存活的会话 id 全集(盘上快照 ∪ 内存活跃,调用方负责并集)。 */\n liveSessionIds: ReadonlySet<string>\n logger: Logger\n /** 'delete'(缺省)| 'dry-run' | 'off' */\n mode?: 'delete' | 'dry-run' | 'off'\n}\n\nexport interface TraceOrphanSweepResult {\n scanned: number\n orphans: number\n deleted: number\n reclaimedBytes: number\n}\n\n/** 从 append-log 文件名还原 streamId(encodeURIComponent(sessionId) + 扩展名)。 */\nfunction streamIdOf(fileName: string): string | undefined {\n const dot = fileName.indexOf('.')\n if (dot <= 0) return undefined\n try {\n return decodeURIComponent(fileName.slice(0, dot))\n } catch {\n return undefined\n }\n}\n\nexport async function sweepOrphanTraces(\n options: TraceOrphanSweepOptions,\n): Promise<TraceOrphanSweepResult> {\n const mode = options.mode ?? 'delete'\n const result: TraceOrphanSweepResult = { scanned: 0, orphans: 0, deleted: 0, reclaimedBytes: 0 }\n if (mode === 'off') return result\n\n for (const dir of options.dirs) {\n let files: string[]\n try {\n files = await readdir(dir)\n } catch {\n continue // 目录不存在(新装/远端后端)→ 无事可做\n }\n for (const file of files) {\n const id = streamIdOf(file)\n if (!id) continue\n result.scanned++\n if (options.liveSessionIds.has(id)) continue\n result.orphans++\n const path = join(dir, file)\n let size = 0\n try {\n size = (await stat(path)).size\n } catch { /* 统计失败不影响删除 */ }\n if (mode === 'dry-run') {\n options.logger.info({ path, size }, 'Orphan trace file (dry-run, not deleted)')\n continue\n }\n try {\n await unlink(path)\n result.deleted++\n result.reclaimedBytes += size\n } catch (error) {\n options.logger.warn(\n { path, err: error instanceof Error ? error.message : String(error) },\n 'Failed to delete orphan trace file',\n )\n }\n }\n }\n\n if (result.orphans > 0) {\n options.logger.info(\n {\n scanned: result.scanned,\n orphans: result.orphans,\n deleted: result.deleted,\n reclaimedMB: Math.round(result.reclaimedBytes / 1e6),\n mode,\n },\n 'Orphan trace sweep completed',\n )\n }\n return result\n}\n"],"mappings":"kGAwBA,SAAS,EAAW,EAAsC,CACxD,IAAM,EAAM,EAAS,QAAQ,IAAI,CAC7B,QAAO,GACX,GAAI,CACF,OAAO,mBAAmB,EAAS,MAAM,EAAG,EAAI,CAAC,MAC3C,CACN,QAIJ,eAAsB,EACpB,EACiC,CACjC,IAAM,EAAO,EAAQ,MAAQ,SACvB,EAAiC,CAAE,QAAS,EAAG,QAAS,EAAG,QAAS,EAAG,eAAgB,EAAG,CAChG,GAAI,IAAS,MAAO,OAAO,EAE3B,IAAK,IAAM,KAAO,EAAQ,KAAM,CAC9B,IAAI,EACJ,GAAI,CACF,EAAQ,MAAM,EAAQ,EAAI,MACpB,CACN,SAEF,IAAK,IAAM,KAAQ,EAAO,CACxB,IAAM,EAAK,EAAW,EAAK,CAG3B,GAFI,CAAC,IACL,EAAO,UACH,EAAQ,eAAe,IAAI,EAAG,EAAE,SACpC,EAAO,UACP,IAAM,EAAO,EAAK,EAAK,EAAK,CACxB,EAAO,EACX,GAAI,CACF,GAAQ,MAAM,EAAK,EAAK,EAAE,UACpB,EACR,GAAI,IAAS,UAAW,CACtB,EAAQ,OAAO,KAAK,CAAE,OAAM,OAAM,CAAE,2CAA2C,CAC/E,SAEF,GAAI,CACF,MAAM,EAAO,EAAK,CAClB,EAAO,UACP,EAAO,gBAAkB,QAClB,EAAO,CACd,EAAQ,OAAO,KACb,CAAE,OAAM,IAAK,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAAE,CACrE,qCACD,GAiBP,OAZI,EAAO,QAAU,GACnB,EAAQ,OAAO,KACb,CACE,QAAS,EAAO,QAChB,QAAS,EAAO,QAChB,QAAS,EAAO,QAChB,YAAa,KAAK,MAAM,EAAO,eAAiB,IAAI,CACpD,OACD,CACD,+BACD,CAEI"}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@x-otto/coding",
3
+ "version": "0.0.1-alpha.0",
4
+ "files": [
5
+ "dist"
6
+ ],
7
+ "type": "module",
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ }
15
+ },
16
+ "publishConfig": {
17
+ "access": "public",
18
+ "registry": "https://registry.npmjs.org",
19
+ "tag": "alpha"
20
+ },
21
+ "dependencies": {
22
+ "@x-otto/agent": "0.0.1-alpha.0",
23
+ "@x-otto/claude-compat": "0.0.1-alpha.0",
24
+ "@x-otto/schedule": "0.0.1-alpha.0",
25
+ "@x-otto/ai": "0.0.1-alpha.0",
26
+ "@x-otto/provider": "0.1.0-alpha.1",
27
+ "@x-otto/devtools": "0.0.1-alpha.0",
28
+ "@x-otto/env": "0.1.0-alpha.1",
29
+ "@x-otto/hooks": "0.0.1-alpha.0",
30
+ "@x-otto/install": "0.0.1-alpha.0",
31
+ "@x-otto/mcp": "0.0.1-alpha.0",
32
+ "@x-otto/memory": "0.0.1-alpha.0",
33
+ "@x-otto/notification": "0.0.1-alpha.0",
34
+ "@x-otto/orchestration-contracts": "0.0.1-alpha.0",
35
+ "@x-otto/orchestrator": "0.0.1-alpha.0",
36
+ "@x-otto/persistence": "0.0.1-alpha.0",
37
+ "@x-otto/plugin": "0.1.0-alpha.1",
38
+ "@x-otto/prompt": "0.0.1-alpha.0",
39
+ "@x-otto/interchange": "0.1.0-alpha.1",
40
+ "@x-otto/runtime": "0.0.1-alpha.0",
41
+ "@x-otto/session": "0.0.1-alpha.0",
42
+ "@x-otto/session-contract": "0.0.1-alpha.0",
43
+ "@x-otto/setting": "0.0.1-alpha.0",
44
+ "@x-otto/shared": "0.1.0-alpha.1",
45
+ "@x-otto/skill": "0.0.1-alpha.0",
46
+ "@x-otto/tools": "0.0.1-alpha.0",
47
+ "@x-otto/workspace": "0.0.1-alpha.0",
48
+ "esbuild": "0.27.7"
49
+ },
50
+ "private": false,
51
+ "scripts": {
52
+ "run:example:auth": "tsx example/auth-store-example.ts",
53
+ "run:example": "tsx example/app-example.tsx",
54
+ "run:example:smoke": "tsx example/app-smoke.tsx",
55
+ "run:example:simple": "tsx example/simple-task.ts",
56
+ "run:example:simple:write": "tsx example/simple-write-file-task.ts",
57
+ "run:example:complex": "tsx example/complex-task.ts",
58
+ "run:example:complex:vite": "tsx example/complex-vite-task.ts",
59
+ "run:example:service": "tsx example/web-service.ts",
60
+ "run:example:devtools-service": "tsx example/devtools-service.ts",
61
+ "run:example:compare": "tsx example/model-compare.ts",
62
+ "build": "tsdown",
63
+ "typecheck:project": "tsc -p tsconfig.json --noEmit",
64
+ "typecheck:file": "tsc src/index.ts --noEmit --target ES2024 --module ESNext --moduleResolution bundler --esModuleInterop --skipLibCheck",
65
+ "typecheck": "tsc --noEmit",
66
+ "clean": "rm -rf dist"
67
+ }
68
+ }