gisool 0.0.0-stage → 0.1.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 +22 -0
- package/README.md +136 -2
- package/dist/api/routes.js +166 -0
- package/dist/api/security.js +86 -0
- package/dist/api/sse.js +55 -0
- package/dist/api/static.js +32 -0
- package/dist/catalog/fields.js +146 -0
- package/dist/catalog/index.js +133 -0
- package/dist/catalog/scanner.js +185 -0
- package/dist/catalog/uri.js +41 -0
- package/dist/catalog/watcher.js +59 -0
- package/dist/cli/config-writer.js +255 -0
- package/dist/cli/doctor.js +197 -0
- package/dist/cli/eval.js +64 -0
- package/dist/cli/export-import.js +66 -0
- package/dist/cli/init.js +271 -0
- package/dist/cli/main.js +165 -0
- package/dist/cli/open.js +24 -0
- package/dist/cli/serve.js +144 -0
- package/dist/config.js +78 -0
- package/dist/dashboard/assets/app.js +256 -0
- package/dist/dashboard/assets/chunk-4U4GNPH4.js +17 -0
- package/dist/dashboard/assets/chunk-5DFWNJC2.js +1 -0
- package/dist/dashboard/assets/chunk-JPIEF5XO.js +17 -0
- package/dist/dashboard/assets/chunk-ZBUKVJOI.js +1 -0
- package/dist/dashboard/assets/styles.css +487 -0
- package/dist/dashboard/index.html +15 -0
- package/dist/ingest/attribution.js +55 -0
- package/dist/ingest/hooks.js +168 -0
- package/dist/ingest/mcp-recorder.js +41 -0
- package/dist/ingest/otlp.js +160 -0
- package/dist/ingest/pipeline.js +100 -0
- package/dist/ingest/redact.js +36 -0
- package/dist/ingest/runtimes.js +25 -0
- package/dist/mcp/http.js +84 -0
- package/dist/mcp/skills-extension.js +35 -0
- package/dist/mcp/stdio-proxy.js +53 -0
- package/dist/mcp/tools.js +164 -0
- package/dist/packs/claude-code.js +157 -0
- package/dist/packs/codex.js +148 -0
- package/dist/packs/cursor.js +95 -0
- package/dist/packs/gajae.js +7 -0
- package/dist/packs/gemini.js +88 -0
- package/dist/packs/json-config.js +51 -0
- package/dist/packs/omo.js +149 -0
- package/dist/packs/openclaw.js +119 -0
- package/dist/packs/registry.js +13 -0
- package/dist/search/fts.js +61 -0
- package/dist/search/fusion.js +50 -0
- package/dist/search/guidance.js +7 -0
- package/dist/search/index.js +74 -0
- package/dist/search/lexical.js +69 -0
- package/dist/server.js +216 -0
- package/dist/store/db.js +74 -0
- package/dist/store/export.js +199 -0
- package/dist/store/index.js +13 -0
- package/dist/store/queries.js +458 -0
- package/dist/store/schema.sql +96 -0
- package/dist/store/writes.js +172 -0
- package/dist/types.js +1 -0
- package/dist/version.js +19 -0
- package/package.json +46 -4
- package/packs/claude-code/README.md +5 -0
- package/packs/claude-code/settings.template.json +24 -0
- package/packs/codex/README.md +5 -0
- package/packs/codex/config.template.toml +11 -0
- package/packs/cursor/hooks.example.json +8 -0
- package/packs/cursor/mcp.example.json +8 -0
- package/packs/gajae/extension/discovery.md +5 -0
- package/packs/gajae/extension/index.js +44 -0
- package/packs/gemini/settings.example.json +16 -0
- package/packs/hook-post.mjs +29 -0
- package/packs/omo/extension/discovery.md +5 -0
- package/packs/omo/extension/index.js +44 -0
- package/packs/openclaw/.codex-plugin/plugin.json +11 -0
- package/packs/openclaw/.mcp.json +12 -0
- package/packs/openclaw/gisool.json +1 -0
- package/packs/openclaw/hooks/gisool-discovery/HOOK.md +8 -0
- package/packs/openclaw/hooks/gisool-discovery/handler.js +27 -0
- package/packs/openclaw/index.mjs +47 -0
- package/packs/openclaw/openclaw.plugin.json +22 -0
- package/packs/openclaw/package.json +11 -0
- package/src/store/schema.sql +96 -0
- package/src/store/task-types.json +15 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
var s="Deterministic fixtures for `?fixtures=1` (40 sessions), `?fixtures=12` (12 sessions), `?fixtures=empty` (no events). Generated for visual work; not real data.",a={attributionRate:{"claude-code":1,codex:.95,gemini:0,cursor:0,omo:0,gajae:1,openclaw:0,unknown:0},abstainRate:.16,unusedSkills:["skill://local/agents/calendar-brief/SKILL.md"],lastEventTs:1791803932125,lastEventByRuntime:{codex:1791803932125,gajae:1791780277431,"claude-code":1791187883789},ingest:{accepted:412,rejected:3,dropped:1,lastError:{ts:1791796732125,code:"payload_too_large"}}},o={attributionRate:{"claude-code":0,codex:0,gemini:0,cursor:0,omo:0,gajae:0,openclaw:0,unknown:0},abstainRate:0,unusedSkills:["skill://local/agents/pr-review-ko/SKILL.md","skill://local/agents/api-contract/SKILL.md","skill://local/agents/db-migration/SKILL.md","skill://local/agents/status-brief/SKILL.md","skill://local/agents/meeting-notes/SKILL.md","skill://local/agents/terraform-r2/SKILL.md","skill://local/agents/deploy-checklist/SKILL.md","skill://local/agents/calendar-brief/SKILL.md"],lastEventByRuntime:{},ingest:{accepted:0,rejected:2,dropped:0,lastError:{ts:179186004e4,code:"unauthorized"}}},i=[{uri:"skill://local/agents/pr-review-ko/SKILL.md",rootId:"agents",dir:"pr-review-ko",name:"pr-review-ko",description:"Reviews a pull request and writes Korean review comments with risk notes.",tags:["review","git"],whenToUse:"Use when the task is review-related.",examples:["\uC774 PR \uB9AC\uBDF0\uD574\uC918","review this diff"],aliasesKo:["PR \uB9AC\uBDF0","\uCF54\uB4DC\uB9AC\uBDF0"],invocation:"automatic",bodyHead:`# pr-review-ko
|
|
2
|
+
|
|
3
|
+
Reviews a pull request and writes Korean review comments with risk notes.`,digest:"662e711c4c69252f",manifestDigest:"0ecb449f581a71ca",resources:[{uri:"skill://local/agents/pr-review-ko/references/checklist.md",digest:"81fa30f437f17957",size:900}],mtimeMs:1791774e6},{uri:"skill://local/agents/api-contract/SKILL.md",rootId:"agents",dir:"api-contract",name:"api-contract",description:"Keeps HTTP API request/response contracts in sync with handlers and docs.",tags:["api","backend"],whenToUse:"Use when the task is api-related.",examples:["API \uC751\uB2F5\uC5D0 \uD544\uB4DC \uCD94\uAC00"],aliasesKo:["API \uACC4\uC57D","\uC751\uB2F5 \uC2A4\uD0A4\uB9C8"],invocation:"automatic",bodyHead:`# api-contract
|
|
4
|
+
|
|
5
|
+
Keeps HTTP API request/response contracts in sync with handlers and docs.`,digest:"91a04d47661b90ac",manifestDigest:"9b130c1b727a7795",resources:[],mtimeMs:17916876e5},{uri:"skill://local/agents/db-migration/SKILL.md",rootId:"agents",dir:"db-migration",name:"db-migration",description:"Writes reversible SQL migrations with backfill and rollback steps.",tags:["db","sql"],whenToUse:"Use when the task is db-related.",examples:["\uD14C\uC774\uBE14\uC5D0 \uCEEC\uB7FC \uCD94\uAC00"],aliasesKo:["\uB9C8\uC774\uADF8\uB808\uC774\uC158","\uCEEC\uB7FC \uCD94\uAC00"],invocation:"automatic",bodyHead:`# db-migration
|
|
6
|
+
|
|
7
|
+
Writes reversible SQL migrations with backfill and rollback steps.`,digest:"f74ca9c53a224b53",manifestDigest:"e69fd1dae449ae8b",resources:[{uri:"skill://local/agents/db-migration/references/checklist.md",digest:"d10528720a401b33",size:974}],mtimeMs:17916012e5},{uri:"skill://local/agents/status-brief/SKILL.md",rootId:"agents",dir:"status-brief",name:"status-brief",description:"Turns recent work into a short status briefing for a team channel.",tags:["docs","writing"],whenToUse:"Use when the task is docs-related.",examples:["\uC774\uBC88 \uC8FC \uC9C4\uD589 \uC0C1\uD669 \uC694\uC57D"],aliasesKo:["\uC0C1\uD669 \uACF5\uC720","\uC9C4\uD589 \uC0C1\uD669"],invocation:"automatic",bodyHead:`# status-brief
|
|
8
|
+
|
|
9
|
+
Turns recent work into a short status briefing for a team channel.`,digest:"949e2fd10a565ef4",manifestDigest:"a85242479b3e3a17",resources:[],mtimeMs:17915148e5},{uri:"skill://local/agents/meeting-notes/SKILL.md",rootId:"agents",dir:"meeting-notes",name:"meeting-notes",description:"Drafts meeting prep and follow-up notes from a short agenda.",tags:["docs","meeting"],whenToUse:"Use when the task is docs-related.",examples:["\uBBF8\uD305 \uC815\uB9AC\uD574\uC11C \uACF5\uC720"],aliasesKo:["\uD68C\uC758\uB85D","\uBBF8\uD305 \uC815\uB9AC"],invocation:"automatic",bodyHead:`# meeting-notes
|
|
10
|
+
|
|
11
|
+
Drafts meeting prep and follow-up notes from a short agenda.`,digest:"ee64ca46a7a4829d",manifestDigest:"6be86d6130aca702",resources:[{uri:"skill://local/agents/meeting-notes/references/checklist.md",digest:"5a0596b6a199b1b7",size:1048}],mtimeMs:17914284e5},{uri:"skill://local/agents/terraform-r2/SKILL.md",rootId:"agents",dir:"terraform-r2",name:"terraform-r2",description:"Provisions Cloudflare R2 buckets and bindings with Terraform.",tags:["infra","terraform"],whenToUse:"Use when the task is infra-related.",examples:["Terraform\uC73C\uB85C \uBC84\uD0B7 \uB9CC\uB4E4\uAE30"],aliasesKo:["R2 \uBC84\uD0B7","\uD14C\uB77C\uD3FC"],invocation:"automatic",bodyHead:`# terraform-r2
|
|
12
|
+
|
|
13
|
+
Provisions Cloudflare R2 buckets and bindings with Terraform.`,digest:"5c957d7671d13399",manifestDigest:"2fb203968f806b20",resources:[],mtimeMs:1791342e6},{uri:"skill://local/agents/deploy-checklist/SKILL.md",rootId:"agents",dir:"deploy-checklist",name:"deploy-checklist",description:"Runs the staging and production deploy checklist and records receipts.",tags:["infra","deploy"],whenToUse:"Use when the task is infra-related.",examples:["\uBC30\uD3EC \uC804 \uC810\uAC80"],aliasesKo:["\uBC30\uD3EC \uCCB4\uD06C\uB9AC\uC2A4\uD2B8"],invocation:"automatic",bodyHead:`# deploy-checklist
|
|
14
|
+
|
|
15
|
+
Runs the staging and production deploy checklist and records receipts.`,digest:"f22b656ebae2411f",manifestDigest:"27bff77a3705e3f1",resources:[{uri:"skill://local/agents/deploy-checklist/references/checklist.md",digest:"f272c78d9517e88c",size:1122}],mtimeMs:17912556e5},{uri:"skill://local/agents/calendar-brief/SKILL.md",rootId:"agents",dir:"calendar-brief",name:"calendar-brief",description:"Summarizes tomorrow's calendar into a short brief.",tags:["docs","calendar"],whenToUse:"Use when the task is docs-related.",examples:["\uB0B4\uC77C \uC77C\uC815 \uC815\uB9AC"],aliasesKo:["\uC77C\uC815 \uBE0C\uB9AC\uD551"],invocation:"automatic",bodyHead:`# calendar-brief
|
|
16
|
+
|
|
17
|
+
Summarizes tomorrow's calendar into a short brief.`,digest:"be8fe6568563b4b5",manifestDigest:"3545f618d6599c32",resources:[],mtimeMs:17911692e5}],r=[{id:"ses_770bad4531",runtime:"codex",startedAt:1791802312155,endedAt:1791803932125,firstPrompt:"Review the auth refactor diff and flag anything that changes session expiry",skills:["skill://local/agents/pr-review-ko/SKILL.md"],state:"loaded",attribution:"vendor_meta"},{id:"ses_1fe658341a",runtime:"gajae",startedAt:1791779866963,endedAt:1791780277431,firstPrompt:"PR #212 \uB9AC\uBDF0\uD558\uACE0 \uB9AC\uC2A4\uD06C \uC815\uB9AC\uD574\uC918",skills:["skill://local/agents/pr-review-ko/SKILL.md"],state:"loaded",attribution:"trace_handle"},{id:"ses_4062597243",runtime:"gajae",startedAt:1791708135397,endedAt:1791709398709,firstPrompt:"\uC774\uBC88 \uC8FC \uC9C4\uD589 \uC0C1\uD669 \uC694\uC57D\uD574\uC11C status \uBE0C\uB9AC\uD551 \uC368\uC918",skills:["skill://local/agents/meeting-notes/SKILL.md"],state:"loaded",attribution:"trace_handle"},{id:"unattributed",runtime:"codex",startedAt:1791700762230,skills:["skill://local/agents/pr-review-ko/SKILL.md"],state:"loaded",attribution:"none",attributionReason:"ambiguous"},{id:"ses_50dc2cf1e4",runtime:"codex",startedAt:1791700102230,endedAt:1791701471616,firstPrompt:"\uB0B4\uC77C \uC624\uC804 \uBBF8\uD305 \uC815\uB9AC\uD574\uC11C \uD300\uC5D0 \uACF5\uC720\uD560 \uCD08\uC548 \uB9CC\uB4E4\uC5B4\uC918",skills:["skill://local/agents/meeting-notes/SKILL.md"],state:"loaded",attribution:"vendor_meta"},{id:"ses_0f3e334360",runtime:"gajae",startedAt:1791547908239,endedAt:1791549883589,firstPrompt:"https://github.com/changeroa/gisul/pull/212/files#diff-9f1a3c0b2d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0 \uB9AC\uBDF0",skills:["skill://local/agents/meeting-notes/SKILL.md"],state:"loaded",attribution:"trace_handle"},{id:"ses_24439de297",runtime:"gajae",startedAt:1791536827555,endedAt:1791537590507,firstPrompt:"\uC8FC\uBB38 \uD14C\uC774\uBE14\uC5D0 \uC0C1\uD0DC \uCEEC\uB7FC \uCD94\uAC00\uD558\uACE0 API \uC751\uB2F5\uC5D0\uB3C4 \uBC18\uC601",skills:["skill://local/agents/db-migration/SKILL.md"],state:"loaded",attribution:"trace_handle"},{id:"ses_0673bfc400",runtime:"codex",startedAt:1791510567915,endedAt:1791511841798,firstPrompt:"\uC8FC\uBB38 \uC0C1\uD0DC \uCEEC\uB7FC\uC744 \uCD94\uAC00\uD558\uBA74\uC11C \uAE30\uC874 \uC8FC\uBB38 \uB370\uC774\uD130\uB294 \uBAA8\uB450 'pending'\uC73C\uB85C \uBC31\uD544\uD558\uACE0, API \uC751\uB2F5 \uC2A4\uD0A4\uB9C8\uC640 OpenAPI \uBB38\uC11C, \uADF8\uB9AC\uACE0 \uD504\uB860\uD2B8\uC5D4\uB4DC \uD0C0\uC785 \uC815\uC758\uAE4C\uC9C0 \uD55C \uBC88\uC5D0 \uB9DE\uCDB0\uC918. \uB9C8\uC774\uADF8\uB808\uC774\uC158\uC740 \uB864\uBC31 \uAC00\uB2A5\uD574\uC57C \uD558\uACE0 \uBC30\uD3EC \uC911\uC5D0\uB3C4 \uC77D\uAE30 \uC694\uCCAD\uC774 \uC2E4\uD328\uD558\uBA74 \uC548 \uB3FC.",skills:["skill://local/agents/meeting-notes/SKILL.md","skill://local/agents/status-brief/SKILL.md"],state:"loaded",attribution:"runtime_id"},{id:"ses_e6e78509e2",runtime:"codex",startedAt:1791459036088,endedAt:1791460927700,firstPrompt:"\uC774 \uD568\uC218 \uB9AC\uD329\uD1A0\uB9C1\uD574\uC11C \uD14C\uC2A4\uD2B8 \uCD94\uAC00\uD574\uC918",skills:["skill://local/agents/status-brief/SKILL.md"],state:"exposed_only",attribution:"runtime_id"},{id:"ses_403828dea4",runtime:"gajae",startedAt:1791440044550,endedAt:1791441727042,skills:[],state:"aborted",attribution:"window"},{id:"ses_784d05179e",runtime:"gajae",startedAt:1791365279717,endedAt:1791365865171,firstPrompt:"staging \uBC30\uD3EC \uCCB4\uD06C\uB9AC\uC2A4\uD2B8 \uB3CC\uB824\uC918",skills:["skill://local/agents/terraform-r2/SKILL.md"],state:"exposed_only",attribution:"trace_handle"},{id:"ses_4cb9ff4eb1",runtime:"codex",startedAt:1791355664429,endedAt:1791357074941,firstPrompt:"\uC774 PR \uB9AC\uBDF0\uD574\uC918, \uD55C\uAD6D\uC5B4\uB85C \uCF54\uBA58\uD2B8",skills:["skill://local/agents/pr-review-ko/SKILL.md"],state:"loaded",attribution:"vendor_meta"},{id:"ses_b143443884",runtime:"codex",startedAt:1791280190181,endedAt:1791281960858,firstPrompt:"\uC774 \uBCC0\uACBD\uC0AC\uD56D \uCF54\uB4DC\uB9AC\uBDF0 \uD574\uC918. \uD14C\uC2A4\uD2B8 \uB204\uB77D \uC788\uB294\uC9C0\uB3C4 \uBD10\uC918",skills:[],state:"not_used",attribution:"vendor_meta"},{id:"ses_6b52ae4f2b",runtime:"codex",startedAt:1791252605864,endedAt:1791253905249,firstPrompt:"\uB9B4\uB9AC\uC988 \uB178\uD2B8 \uCD08\uC548 \uC791\uC131\uD574\uC918",skills:["skill://local/agents/meeting-notes/SKILL.md","skill://local/agents/status-brief/SKILL.md"],state:"loaded",attribution:"vendor_meta"},{id:"ses_ec401655c2",runtime:"claude-code",startedAt:1791185662397,endedAt:1791187883789,firstPrompt:"Write a migration that adds an index on orders(status) and backfills the column",skills:["skill://local/agents/db-migration/SKILL.md"],state:"loaded",attribution:"runtime_id"},{id:"ses_d7e6d472e7",runtime:"claude-code",startedAt:1791173734458,endedAt:1791174578523,firstPrompt:"\uC774\uBC88 \uC8FC \uC9C4\uD589 \uC0C1\uD669 \uC694\uC57D\uD574\uC11C status \uBE0C\uB9AC\uD551 \uC368\uC918",skills:[],state:"no_match",attribution:"trace_handle"},{id:"ses_a4c604eb0f",runtime:"claude-code",startedAt:1790926834981,endedAt:1790927279548,firstPrompt:"Explain how the hook forwarder handles timeouts and retries",skills:[],state:"no_match",attribution:"runtime_id"},{id:"ses_149b077f7d",runtime:"claude-code",startedAt:1790906028007,endedAt:1790907504361,firstPrompt:"Summarize the deployment doc and list the open risks",skills:[],state:"aborted",attribution:"runtime_id"},{id:"ses_fbee7e136c",runtime:"codex",startedAt:1790852853387,endedAt:1790854155572,firstPrompt:"DB \uC870\uD68C\uAC00 \uB108\uBB34 \uB290\uB824\uC11C \uC6D0\uC778 \uC880 \uBD10\uC918",skills:["skill://local/agents/db-migration/SKILL.md"],state:"loaded",attribution:"vendor_meta"},{id:"ses_5c8ae46af5",runtime:"codex",startedAt:1790818284500,endedAt:1790818967566,firstPrompt:"\uC774 \uBCC0\uACBD\uC0AC\uD56D \uCF54\uB4DC\uB9AC\uBDF0 \uD574\uC918. \uD14C\uC2A4\uD2B8 \uB204\uB77D \uC788\uB294\uC9C0\uB3C4 \uBD10\uC918",skills:[],state:"not_used",attribution:"vendor_meta"},{id:"ses_bb85bd8f72",runtime:"codex",startedAt:1790757635691,endedAt:1790759191653,firstPrompt:"Terraform\uC73C\uB85C R2 \uBC84\uD0B7 \uB9CC\uB4E4\uC5B4\uC918",skills:[],state:"no_match",attribution:"runtime_id"},{id:"ses_f1cc46fbd7",runtime:"claude-code",startedAt:1790670367214,endedAt:1790671465842,firstPrompt:"\uC8FC\uBB38 \uD14C\uC774\uBE14\uC5D0 \uC0C1\uD0DC \uCEEC\uB7FC \uCD94\uAC00\uD558\uACE0 API \uC751\uB2F5\uC5D0\uB3C4 \uBC18\uC601",skills:["skill://local/agents/db-migration/SKILL.md"],state:"exposed_only",attribution:"runtime_id"},{id:"ses_453285f7a8",runtime:"claude-code",startedAt:1790652394408,endedAt:1790655029144,firstPrompt:"PR #212 \uB9AC\uBDF0\uD558\uACE0 \uB9AC\uC2A4\uD06C \uC815\uB9AC\uD574\uC918",skills:["skill://local/agents/pr-review-ko/SKILL.md"],state:"loaded",attribution:"runtime_id"},{id:"ses_13444120fd",runtime:"claude-code",startedAt:1790644907370,endedAt:1790645724614,firstPrompt:"\uB9B4\uB9AC\uC988 \uB178\uD2B8 \uCD08\uC548 \uC791\uC131\uD574\uC918",skills:["skill://local/agents/meeting-notes/SKILL.md"],state:"loaded",attribution:"trace_handle"},{id:"ses_6885a11728",runtime:"codex",startedAt:1790575143468,endedAt:1790577242922,firstPrompt:"\uB0B4\uC77C \uC624\uC804 \uBBF8\uD305 \uC815\uB9AC\uD574\uC11C \uD300\uC5D0 \uACF5\uC720\uD560 \uCD08\uC548 \uB9CC\uB4E4\uC5B4\uC918",skills:["skill://local/agents/status-brief/SKILL.md"],state:"exposed_only",attribution:"vendor_meta"},{id:"ses_4445eb2419",runtime:"gajae",startedAt:1790563241893,endedAt:1790563914526,firstPrompt:"DB \uC870\uD68C\uAC00 \uB108\uBB34 \uB290\uB824\uC11C \uC6D0\uC778 \uC880 \uBD10\uC918",skills:["skill://local/agents/db-migration/SKILL.md"],state:"exposed_only",attribution:"trace_handle"},{id:"ses_161ef32fa8",runtime:"codex",startedAt:1790427018548,endedAt:1790427817251,firstPrompt:"Summarize the deployment doc and list the open risks",skills:["skill://local/agents/meeting-notes/SKILL.md","skill://local/agents/status-brief/SKILL.md"],state:"loaded",attribution:"runtime_id"},{id:"ses_0f5aed7e3b",runtime:"claude-code",startedAt:1790324358656,endedAt:1790326252436,firstPrompt:"DB \uC870\uD68C\uAC00 \uB108\uBB34 \uB290\uB824\uC11C \uC6D0\uC778 \uC880 \uBD10\uC918",skills:["skill://local/agents/db-migration/SKILL.md"],state:"loaded",attribution:"runtime_id"},{id:"ses_ac514fa3a9",runtime:"claude-code",startedAt:1790240018747,endedAt:1790242557112,firstPrompt:"Write a migration that adds an index on orders(status) and backfills the column",skills:["skill://local/agents/db-migration/SKILL.md","skill://local/agents/api-contract/SKILL.md"],state:"loaded",attribution:"runtime_id"},{id:"ses_9cc9814963",runtime:"claude-code",startedAt:1790209111983,endedAt:1790209936487,firstPrompt:"\uC774\uBC88 \uC8FC \uC9C4\uD589 \uC0C1\uD669 \uC694\uC57D\uD574\uC11C status \uBE0C\uB9AC\uD551 \uC368\uC918",skills:["skill://local/agents/status-brief/SKILL.md"],state:"exposed_only",attribution:"runtime_id"},{id:"ses_4eee4d5d2a",runtime:"codex",startedAt:1790139736444,endedAt:1790141882919,firstPrompt:"\uC138\uC158 \uD2B8\uB808\uC774\uC2A4 \uD654\uBA74\uC5D0 \uB4E4\uC5B4\uAC08 \uB370\uC774\uD130 \uAD6C\uC870 \uC124\uACC4\uD574\uC918",skills:[],state:"no_match",attribution:"vendor_meta"},{id:"ses_9c562959f6",runtime:"gajae",startedAt:1790064715443,endedAt:1790065692745,firstPrompt:"\uC774 \uD568\uC218 \uB9AC\uD329\uD1A0\uB9C1\uD574\uC11C \uD14C\uC2A4\uD2B8 \uCD94\uAC00\uD574\uC918",skills:[],state:"no_match",attribution:"window"},{id:"ses_e1777b641f",runtime:"codex",startedAt:1789995822654,endedAt:1789998102760,firstPrompt:"users API\uC5D0 \uCEE4\uC11C \uAE30\uBC18 \uD398\uC774\uC9C0\uB124\uC774\uC158 \uCD94\uAC00",skills:["skill://local/agents/db-migration/SKILL.md"],state:"loaded",attribution:"vendor_meta"},{id:"ses_e3e1babe95",runtime:"codex",startedAt:1789988011694,endedAt:1789988690957,firstPrompt:"staging \uBC30\uD3EC \uCCB4\uD06C\uB9AC\uC2A4\uD2B8 \uB3CC\uB824\uC918",skills:["skill://local/agents/terraform-r2/SKILL.md","skill://local/agents/deploy-checklist/SKILL.md"],state:"loaded",attribution:"runtime_id"},{id:"ses_359f478748",runtime:"claude-code",startedAt:1789965165028,endedAt:1789965534845,firstPrompt:"users API\uC5D0 \uCEE4\uC11C \uAE30\uBC18 \uD398\uC774\uC9C0\uB124\uC774\uC158 \uCD94\uAC00",skills:["skill://local/agents/db-migration/SKILL.md"],state:"loaded",attribution:"runtime_id"},{id:"ses_5349b12304",runtime:"codex",startedAt:1789953556927,endedAt:1789955692e3,firstPrompt:"Set up a GitHub Actions workflow that runs the test suite on pull requests",skills:["skill://local/agents/terraform-r2/SKILL.md","skill://local/agents/deploy-checklist/SKILL.md"],state:"loaded",attribution:"vendor_meta"},{id:"ses_85deb86473",runtime:"claude-code",startedAt:1789725905735,endedAt:1789727794984,firstPrompt:"\uC774 \uD568\uC218 \uB9AC\uD329\uD1A0\uB9C1\uD574\uC11C \uD14C\uC2A4\uD2B8 \uCD94\uAC00\uD574\uC918",skills:[],state:"no_match",attribution:"trace_handle"},{id:"ses_ec34df6505",runtime:"gajae",startedAt:1789636685863,endedAt:1789638861315,firstPrompt:"DB \uC870\uD68C\uAC00 \uB108\uBB34 \uB290\uB824\uC11C \uC6D0\uC778 \uC880 \uBD10\uC918",skills:[],state:"not_used",attribution:"trace_handle"},{id:"ses_c51fa4cdc4",runtime:"codex",startedAt:1789627907572,endedAt:1789630289429,firstPrompt:"staging \uBC30\uD3EC \uCCB4\uD06C\uB9AC\uC2A4\uD2B8 \uB3CC\uB824\uC918",skills:["skill://local/agents/terraform-r2/SKILL.md"],state:"loaded",attribution:"vendor_meta"},{id:"ses_cdeb057180",runtime:"codex",startedAt:1789616991909,endedAt:1789619151703,firstPrompt:"\uC8FC\uBB38 \uD14C\uC774\uBE14\uC5D0 \uC0C1\uD0DC \uCEEC\uB7FC \uCD94\uAC00\uD558\uACE0 API \uC751\uB2F5\uC5D0\uB3C4 \uBC18\uC601",skills:["skill://local/agents/db-migration/SKILL.md"],state:"loaded",attribution:"vendor_meta"}],n=["ses_770bad4531","ses_1fe658341a","ses_4062597243","unattributed","ses_50dc2cf1e4","ses_0f3e334360","ses_24439de297","ses_0673bfc400","ses_e6e78509e2","ses_403828dea4","ses_784d05179e","ses_4cb9ff4eb1"],d={ses_ac514fa3a9:[{ts:1790240018747,kind:"session_start",summary:"Session started",detail:{kind:"session_start"}},{ts:1790240020747,kind:"prompt",summary:"Write a migration that adds an index on orders(status) and backfills the column",detail:{kind:"prompt",text:"Write a migration that adds an index on orders(status) and backfills the column",textLength:79}},{ts:1790240021147,kind:"search",summary:"search_skills: 3 candidates, 2 chosen",detail:{kind:"search",traceId:"tr_907d051e",chosen:["skill://local/agents/db-migration/SKILL.md","skill://local/agents/api-contract/SKILL.md"],query:"Write a migration that adds an index on orders(status) and backfills the column",mode:"automatic",candidates:[{uri:"skill://local/agents/db-migration/SKILL.md",name:"db-migration",description:"Writes reversible SQL migrations with backfill and rollback steps.",score:.75,rank:1,invocation:"automatic",digest:"3ded922ddd04",matched:["migration","index","order","statu","backfill","column"]},{uri:"skill://local/codex/db-migration/SKILL.md",name:"db-migration",description:"Writes reversible SQL migrations with backfill and rollback steps.",score:.18,rank:2,invocation:"automatic",digest:"9b1f0c27aa41",matched:["migration","index","backfill"]},{uri:"skill://local/agents/api-contract/SKILL.md",name:"api-contract",description:"Keeps HTTP API request/response contracts in sync with handlers and docs.",score:.18,rank:3,invocation:"automatic",digest:"5ca4fda5d5ce",matched:["order","statu","column"]},{uri:"skill://local/agents/pr-review-ko/SKILL.md",name:"pr-review-ko",description:"Reviews a pull request and writes Korean review comments with risk notes.",score:.06,rank:4,invocation:"automatic",digest:"aca459effbb0",matched:["write"]}],elapsedMs:12,total:4}},{ts:1790240023747,kind:"load",summary:"Loaded db-migration",detail:{kind:"load",uri:"skill://local/agents/db-migration/SKILL.md",loadId:"ld_45601c03",manifestDigest:"3011f937739e79c8"}},{ts:1790240024047,kind:"load",summary:"Loaded api-contract",detail:{kind:"load",uri:"skill://local/agents/api-contract/SKILL.md",loadId:"ld_cbd8dbca",manifestDigest:"915a16e3682db4af"}},{ts:1790240066747,kind:"read_file",summary:"Read references/rollback.md",detail:{kind:"read_file",skillUri:"skill://local/agents/db-migration/SKILL.md",uri:"skill://local/agents/db-migration/references/rollback.md",bytes:2814}},{ts:1790240079747,kind:"read_file",summary:"Read checklist.md",detail:{kind:"read_file",skillUri:"skill://local/agents/api-contract/SKILL.md",uri:"skill://local/agents/api-contract/checklist.md",bytes:1203}},{ts:1790240208747,kind:"native_skill",summary:"Native skill: commit",detail:{kind:"native_skill",name:"commit",via:"tool"}},{ts:1790240348747,kind:"error",summary:"read_skill_file failed: resource_not_found",detail:{kind:"error",code:"resource_not_found",message:"skill://local/agents/db-migration/references/seed.sql is not in the manifest"}},{ts:1790242557112,kind:"session_end",summary:"Session ended",detail:{kind:"session_end"}}],ses_bb85bd8f72:[{ts:1790757635691,kind:"session_start",summary:"Session started",detail:{kind:"session_start"}},{ts:1790757637191,kind:"prompt",summary:"Terraform\uC73C\uB85C R2 \uBC84\uD0B7 \uB9CC\uB4E4\uC5B4\uC918",detail:{kind:"prompt",text:"Terraform\uC73C\uB85C R2 \uBC84\uD0B7 \uB9CC\uB4E4\uC5B4\uC918",textLength:22}},{ts:1790757637591,kind:"search",summary:"search_skills: abstained (no_overlap)",detail:{kind:"search",traceId:"tr_c03785ef",chosen:[],query:"Terraform\uC73C\uB85C R2 \uBC84\uD0B7 \uB9CC\uB4E4\uC5B4\uC918",mode:"automatic",candidates:[],abstained:{reason:"no_overlap",hint:"No skill mentions Terraform or R2; add aliases or a new skill."},elapsedMs:4,total:0}},{ts:1790759191653,kind:"session_end",summary:"Session ended",detail:{kind:"session_end"}}],ses_e6e78509e2:[{ts:1791459036088,kind:"session_start",summary:"Session started",detail:{kind:"session_start"}},{ts:1791459037088,kind:"prompt",summary:"\uC774 \uD568\uC218 \uB9AC\uD329\uD1A0\uB9C1\uD574\uC11C \uD14C\uC2A4\uD2B8 \uCD94\uAC00\uD574\uC918",detail:{kind:"prompt",text:"\uC774 \uD568\uC218 \uB9AC\uD329\uD1A0\uB9C1\uD574\uC11C \uD14C\uC2A4\uD2B8 \uCD94\uAC00\uD574\uC918",textLength:20}},{ts:1791459037388,kind:"search",summary:"search_skills: 2 candidates, none chosen",detail:{kind:"search",traceId:"tr_44e4b7aa",chosen:[],query:"\uC774 \uD568\uC218 \uB9AC\uD329\uD1A0\uB9C1\uD574\uC11C \uD14C\uC2A4\uD2B8 \uCD94\uAC00\uD574\uC918",mode:"automatic",candidates:[{uri:"skill://local/agents/status-brief/SKILL.md",name:"status-brief",description:"Turns recent work into a short status briefing for a team channel.",score:.25,rank:1,invocation:"automatic",digest:"2cdafef7e4aa",matched:["\uCD94\uAC00"]},{uri:"skill://local/agents/meeting-notes/SKILL.md",name:"meeting-notes",description:"Drafts meeting prep and follow-up notes from a short agenda.",score:.12,rank:2,invocation:"automatic",digest:"c64da30b4d65",matched:["\uD14C\uC2A4\uD2B8"]}],elapsedMs:9,total:2}},{ts:1791460927700,kind:"session_end",summary:"Session ended",detail:{kind:"session_end"}}],ses_b143443884:[{ts:1791280190181,kind:"session_start",summary:"Session started",detail:{kind:"session_start"}},{ts:1791280191181,kind:"prompt",summary:"\uC774 \uBCC0\uACBD\uC0AC\uD56D \uCF54\uB4DC\uB9AC\uBDF0 \uD574\uC918. \uD14C\uC2A4\uD2B8 \uB204\uB77D \uC788\uB294\uC9C0\uB3C4 \uBD10\uC918",detail:{kind:"prompt",textLength:30}},{ts:1791281960858,kind:"session_end",summary:"Session ended",detail:{kind:"session_end"}}],ses_149b077f7d:[{ts:1790906028007,kind:"session_start",summary:"Session started",detail:{kind:"session_start"}},{ts:1790906029007,kind:"prompt",summary:"Summarize the deployment doc and list the open risks",detail:{kind:"prompt",text:"Summarize the deployment doc and list the open risks",textLength:52}},{ts:1790906029407,kind:"search",summary:"search_skills: 1 candidate, 1 chosen",detail:{kind:"search",traceId:"tr_24584e23",chosen:["skill://local/agents/pr-review-ko/SKILL.md"],query:"Summarize the deployment doc and list the open risks",mode:"automatic",candidates:[{uri:"skill://local/agents/pr-review-ko/SKILL.md",name:"pr-review-ko",description:"Reviews a pull request and writes Korean review comments with risk notes.",score:.17,rank:1,invocation:"automatic",digest:"e28d51fee54a",matched:["risks"]}],elapsedMs:7,total:1}},{ts:1790906031007,kind:"error",summary:"load_skill aborted: client disconnected",detail:{kind:"error",code:"load_aborted",message:"client closed the MCP session before load_skill completed"}},{ts:1790907504361,kind:"session_end",summary:"Session ended",detail:{kind:"session_end"}}],unattributed:[{ts:1791700762230,kind:"search",summary:"search_skills: 1 candidate, 1 chosen (unattributed: ambiguous)",detail:{kind:"search",traceId:"tr_5e644e47",chosen:["skill://local/agents/pr-review-ko/SKILL.md"],query:"review this PR",mode:"automatic",candidates:[{uri:"skill://local/agents/pr-review-ko/SKILL.md",name:"pr-review-ko",description:"Reviews a pull request and writes Korean review comments with risk notes.",score:.66,rank:1,invocation:"automatic",digest:"f7adeae404c9",matched:["review","PR"]}],elapsedMs:6,total:1}},{ts:1791700764230,kind:"load",summary:"Loaded pr-review-ko",detail:{kind:"load",uri:"skill://local/agents/pr-review-ko/SKILL.md",loadId:"ld_451552c6",manifestDigest:"7f048bb7891e12d4"}}]},l={unit:"first_load",columns:["task_type","skill","state"],nodes:[{id:"t:review",column:0,label:"\uCF54\uB4DC \uB9AC\uBDF0",count:7},{id:"s:pr-review-ko",column:1,label:"pr-review-ko",count:5},{id:"st:loaded",column:2,label:"loaded",count:23},{id:"t:docs",column:0,label:"\uBB38\uC11C\xB7\uACF5\uC720",count:11},{id:"s:meeting-notes",column:1,label:"meeting-notes",count:7},{id:"t:dbapi",column:0,label:"DB\xB7API \uBCC0\uACBD",count:12},{id:"s:db-migration",column:1,label:"db-migration",count:10},{id:"t:other",column:0,label:"\uAE30\uD0C0",count:5},{id:"s:status-brief",column:1,label:"status-brief",count:3},{id:"st:exposed_only",column:2,label:"exposed_only",count:6},{id:"s:none",column:1,label:"(no skill)",count:11},{id:"st:aborted",column:2,label:"aborted",count:2},{id:"s:terraform-r2",column:1,label:"terraform-r2",count:4},{id:"st:not_used",column:2,label:"not_used",count:3},{id:"st:no_match",column:2,label:"no_match",count:6},{id:"t:other-group",column:0,label:"Other",count:5,other:!0}],links:[{source:"t:review",target:"s:pr-review-ko",count:5,state:"loaded"},{source:"s:pr-review-ko",target:"st:loaded",count:5,state:"loaded"},{source:"t:docs",target:"s:meeting-notes",count:7,state:"loaded"},{source:"s:meeting-notes",target:"st:loaded",count:7,state:"loaded"},{source:"t:dbapi",target:"s:db-migration",count:8,state:"loaded"},{source:"s:db-migration",target:"st:loaded",count:8,state:"loaded"},{source:"t:other",target:"s:status-brief",count:1,state:"exposed_only"},{source:"s:status-brief",target:"st:exposed_only",count:3,state:"exposed_only"},{source:"t:dbapi",target:"s:none",count:1,state:"aborted"},{source:"s:none",target:"st:aborted",count:2,state:"aborted"},{source:"t:other-group",target:"s:terraform-r2",count:1,state:"exposed_only"},{source:"s:terraform-r2",target:"st:exposed_only",count:1,state:"exposed_only"},{source:"t:review",target:"s:none",count:2,state:"not_used"},{source:"s:none",target:"st:not_used",count:3,state:"not_used"},{source:"t:docs",target:"s:none",count:1,state:"no_match"},{source:"s:none",target:"st:no_match",count:6,state:"no_match"},{source:"t:other",target:"s:none",count:4,state:"no_match"},{source:"t:docs",target:"s:none",count:1,state:"aborted"},{source:"t:other-group",target:"s:none",count:1,state:"no_match"},{source:"t:dbapi",target:"s:db-migration",count:2,state:"exposed_only"},{source:"s:db-migration",target:"st:exposed_only",count:2,state:"exposed_only"},{source:"t:docs",target:"s:status-brief",count:2,state:"exposed_only"},{source:"t:other-group",target:"s:terraform-r2",count:3,state:"loaded"},{source:"s:terraform-r2",target:"st:loaded",count:3,state:"loaded"},{source:"t:dbapi",target:"s:none",count:1,state:"not_used"}],sessionCount:40},c={unit:"first_load",columns:["task_type","skill","state"],nodes:[{id:"t:review",column:0,label:"\uCF54\uB4DC \uB9AC\uBDF0",count:4},{id:"s:pr-review-ko",column:1,label:"pr-review-ko",count:4},{id:"st:loaded",column:2,label:"loaded",count:9},{id:"t:docs",column:0,label:"\uBB38\uC11C\xB7\uACF5\uC720",count:4},{id:"s:meeting-notes",column:1,label:"meeting-notes",count:4},{id:"t:dbapi",column:0,label:"DB\xB7API \uBCC0\uACBD",count:2},{id:"s:db-migration",column:1,label:"db-migration",count:1},{id:"t:other",column:0,label:"\uAE30\uD0C0",count:1},{id:"s:status-brief",column:1,label:"status-brief",count:1},{id:"st:exposed_only",column:2,label:"exposed_only",count:2},{id:"s:none",column:1,label:"(no skill)",count:1},{id:"st:aborted",column:2,label:"aborted",count:1},{id:"s:terraform-r2",column:1,label:"terraform-r2",count:1},{id:"t:other-group",column:0,label:"Other",count:1,other:!0}],links:[{source:"t:review",target:"s:pr-review-ko",count:4,state:"loaded"},{source:"s:pr-review-ko",target:"st:loaded",count:4,state:"loaded"},{source:"t:docs",target:"s:meeting-notes",count:4,state:"loaded"},{source:"s:meeting-notes",target:"st:loaded",count:4,state:"loaded"},{source:"t:dbapi",target:"s:db-migration",count:1,state:"loaded"},{source:"s:db-migration",target:"st:loaded",count:1,state:"loaded"},{source:"t:other",target:"s:status-brief",count:1,state:"exposed_only"},{source:"s:status-brief",target:"st:exposed_only",count:1,state:"exposed_only"},{source:"t:dbapi",target:"s:none",count:1,state:"aborted"},{source:"s:none",target:"st:aborted",count:1,state:"aborted"},{source:"t:other-group",target:"s:terraform-r2",count:1,state:"exposed_only"},{source:"s:terraform-r2",target:"st:exposed_only",count:1,state:"exposed_only"}],sessionCount:12},u={tz:"Asia/Seoul",weekStart:1,bucketHours:1,cells:[{dow:0,hour:15,count:2},{dow:0,hour:17,count:1},{dow:1,hour:10,count:1},{dow:1,hour:11,count:1},{dow:1,hour:13,count:3},{dow:1,hour:14,count:1},{dow:1,hour:16,count:1},{dow:1,hour:19,count:2},{dow:1,hour:22,count:1},{dow:2,hour:10,count:1},{dow:2,hour:11,count:1},{dow:2,hour:12,count:1},{dow:2,hour:17,count:2},{dow:2,hour:18,count:1},{dow:3,hour:14,count:1},{dow:3,hour:15,count:1},{dow:3,hour:17,count:1},{dow:3,hour:18,count:1},{dow:4,hour:9,count:1},{dow:4,hour:10,count:1},{dow:4,hour:12,count:1},{dow:4,hour:15,count:2},{dow:4,hour:17,count:1},{dow:4,hour:18,count:1},{dow:4,hour:20,count:2},{dow:5,hour:10,count:2},{dow:5,hour:16,count:1},{dow:5,hour:17,count:1},{dow:5,hour:18,count:1},{dow:5,hour:19,count:1},{dow:5,hour:21,count:1},{dow:6,hour:21,count:1}],rowTotals:[3,10,6,4,9,7,1],colTotals:[0,0,0,0,0,0,0,0,0,1,5,2,2,3,2,5,2,6,4,3,2,2,1,0]},m={tz:"Asia/Seoul",weekStart:1,bucketHours:2,cells:[{dow:0,hour:14,count:2},{dow:0,hour:16,count:1},{dow:1,hour:12,count:1},{dow:1,hour:18,count:1},{dow:3,hour:14,count:1},{dow:3,hour:18,count:1},{dow:4,hour:14,count:1},{dow:4,hour:20,count:1},{dow:5,hour:10,count:1},{dow:5,hour:18,count:1},{dow:5,hour:20,count:1}],rowTotals:[3,2,0,2,2,3,0],colTotals:[0,0,0,0,0,1,1,4,1,3,2,0]},k={weeks:["2026-W35","2026-W36","2026-W37","2026-W38","2026-W39","2026-W40","2026-W41","2026-W42"],rows:[{uri:"skill://local/agents/pr-review-ko/SKILL.md",name:"pr-review-ko",counts:[5,6,3,4,1,5,2,2]},{uri:"skill://local/agents/db-migration/SKILL.md",name:"db-migration",counts:[2,0,2,4,6,4,2,0]},{uri:"skill://local/agents/status-brief/SKILL.md",name:"status-brief",counts:[3,3,3,1,3,2,2,0]},{uri:"skill://local/agents/meeting-notes/SKILL.md",name:"meeting-notes",counts:[3,2,1,1,2,1,5,0]},{uri:"skill://local/agents/terraform-r2/SKILL.md",name:"terraform-r2",counts:[2,0,3,4,3,2,0,0]},{uri:"skill://local/agents/deploy-checklist/SKILL.md",name:"deploy-checklist",counts:[1,1,2,3,3,2,0,0]},{uri:"skill://local/agents/api-contract/SKILL.md",name:"api-contract",counts:[0,0,1,1,3,3,0,0]}]},g={weeks:["2026-W35","2026-W36","2026-W37","2026-W38","2026-W39","2026-W40","2026-W41","2026-W42"],rows:[{uri:"skill://local/agents/pr-review-ko/SKILL.md",name:"pr-review-ko",counts:[0,0,0,0,0,0,2,2]},{uri:"skill://local/agents/meeting-notes/SKILL.md",name:"meeting-notes",counts:[0,0,0,0,0,0,4,0]},{uri:"skill://local/agents/db-migration/SKILL.md",name:"db-migration",counts:[0,0,0,0,0,0,1,0]},{uri:"skill://local/agents/status-brief/SKILL.md",name:"status-brief",counts:[0,0,0,0,0,0,1,0]}]},b={$comment:s,stats:a,statsEmpty:o,skills:i,sessions:r,sessions12:n,traces:d,flow:l,flow12:c,heatmap:u,heatmap12:m,skillWeek:k,skillWeek12:g};export{s as $comment,b as default,l as flow,c as flow12,u as heatmap,m as heatmap12,r as sessions,n as sessions12,k as skillWeek,g as skillWeek12,i as skills,a as stats,o as statsEmpty,d as traces};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var u={attributionRate:{"claude-code":1,codex:.95,gemini:null,cursor:null,omo:null,gajae:1,openclaw:null,unknown:null},unattributed:{searches:3,loads:1}},a={attributionRate:{"claude-code":null,codex:null,gemini:null,cursor:null,omo:null,gajae:null,openclaw:null,unknown:null},unattributed:{searches:0,loads:0}},e={stats:u,statsEmpty:a};export{e as default,u as stats,a as statsEmpty};
|
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
/* Tokens: see DESIGN.md (local/dashboard). Light values on :root, dark overrides below. */
|
|
2
|
+
:root {
|
|
3
|
+
color-scheme: light dark;
|
|
4
|
+
--bg: #f7f8f8;
|
|
5
|
+
--surface: #ffffff;
|
|
6
|
+
--surface-2: #f3f4f5;
|
|
7
|
+
--ink: #15171a;
|
|
8
|
+
--ink-2: #5c6069;
|
|
9
|
+
--ink-3: #8a8f98;
|
|
10
|
+
--line: rgba(21, 23, 26, 0.08);
|
|
11
|
+
--line-2: rgba(21, 23, 26, 0.16);
|
|
12
|
+
--wash: rgba(21, 23, 26, 0.04);
|
|
13
|
+
--wash-2: rgba(21, 23, 26, 0.08);
|
|
14
|
+
--accent: #5e6ad2;
|
|
15
|
+
--accent-2: #4f5bc4;
|
|
16
|
+
--accent-wash: color-mix(in srgb, var(--accent) 12%, transparent);
|
|
17
|
+
--ok: #1f8f45;
|
|
18
|
+
--warn: #a8690f;
|
|
19
|
+
--bad: #c0392b;
|
|
20
|
+
--neutral: #8a8f98;
|
|
21
|
+
--shadow-pop: 0 4px 16px rgba(0, 0, 0, 0.18);
|
|
22
|
+
|
|
23
|
+
--font-sans: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, "Apple SD Gothic Neo", "Segoe UI", Roboto, sans-serif;
|
|
24
|
+
--font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
|
25
|
+
--fs-title: 15px;
|
|
26
|
+
--fs-body: 14px;
|
|
27
|
+
--fs-sm: 13px;
|
|
28
|
+
--fs-cap: 12px;
|
|
29
|
+
--fs-micro: 11px;
|
|
30
|
+
|
|
31
|
+
--s-1: 4px;
|
|
32
|
+
--s-2: 8px;
|
|
33
|
+
--s-3: 12px;
|
|
34
|
+
--s-4: 16px;
|
|
35
|
+
--s-5: 20px;
|
|
36
|
+
--s-6: 24px;
|
|
37
|
+
--s-8: 32px;
|
|
38
|
+
--s-12: 48px;
|
|
39
|
+
--max-w: 1180px;
|
|
40
|
+
--gutter: var(--s-4);
|
|
41
|
+
|
|
42
|
+
--r-sm: 6px;
|
|
43
|
+
--r-md: 10px;
|
|
44
|
+
--r-full: 9999px;
|
|
45
|
+
--t-micro: 120ms ease-out;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@media (prefers-color-scheme: dark) {
|
|
49
|
+
:root {
|
|
50
|
+
--bg: #0f1011;
|
|
51
|
+
--surface: #151618;
|
|
52
|
+
--surface-2: #1b1c1e;
|
|
53
|
+
--ink: #f7f8f8;
|
|
54
|
+
--ink-2: #b4b9c2;
|
|
55
|
+
--ink-3: #7f848d;
|
|
56
|
+
--line: rgba(255, 255, 255, 0.08);
|
|
57
|
+
--line-2: rgba(255, 255, 255, 0.16);
|
|
58
|
+
--wash: rgba(255, 255, 255, 0.04);
|
|
59
|
+
--wash-2: rgba(255, 255, 255, 0.08);
|
|
60
|
+
--accent: #7170ff;
|
|
61
|
+
--accent-2: #828fff;
|
|
62
|
+
--accent-wash: color-mix(in srgb, var(--accent) 18%, transparent);
|
|
63
|
+
--ok: #3ccb6a;
|
|
64
|
+
--warn: #e0a84a;
|
|
65
|
+
--bad: #ef6b6b;
|
|
66
|
+
--neutral: #7f848d;
|
|
67
|
+
--shadow-pop: 0 4px 16px rgba(0, 0, 0, 0.5);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@media (min-width: 640px) {
|
|
72
|
+
:root { --gutter: var(--s-6); }
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
76
|
+
|
|
77
|
+
html, body { margin: 0; }
|
|
78
|
+
|
|
79
|
+
body {
|
|
80
|
+
background: var(--bg);
|
|
81
|
+
color: var(--ink);
|
|
82
|
+
font: 400 var(--fs-body) / 1.5 var(--font-sans);
|
|
83
|
+
word-break: keep-all;
|
|
84
|
+
overflow-wrap: anywhere;
|
|
85
|
+
-webkit-font-smoothing: antialiased;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
a { color: var(--accent); }
|
|
89
|
+
a:hover { color: var(--accent-2); }
|
|
90
|
+
|
|
91
|
+
button, input, select { font: inherit; color: inherit; }
|
|
92
|
+
|
|
93
|
+
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
94
|
+
|
|
95
|
+
.wrap { max-width: var(--max-w); margin-inline: auto; padding-inline: var(--gutter); }
|
|
96
|
+
|
|
97
|
+
/* Shell: sticky header block (brand row + tabs), document owns the scroll. */
|
|
98
|
+
.top {
|
|
99
|
+
position: sticky;
|
|
100
|
+
top: 0;
|
|
101
|
+
z-index: 10;
|
|
102
|
+
background: var(--surface);
|
|
103
|
+
border-bottom: 1px solid var(--line);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.top__row {
|
|
107
|
+
display: flex;
|
|
108
|
+
align-items: center;
|
|
109
|
+
flex-wrap: wrap;
|
|
110
|
+
gap: var(--s-2) var(--s-4);
|
|
111
|
+
min-height: 52px;
|
|
112
|
+
padding-block: var(--s-2);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.brand {
|
|
116
|
+
font-size: var(--fs-title);
|
|
117
|
+
font-weight: 600;
|
|
118
|
+
letter-spacing: -0.01em;
|
|
119
|
+
color: var(--ink);
|
|
120
|
+
text-decoration: none;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.live {
|
|
124
|
+
display: inline-flex;
|
|
125
|
+
align-items: center;
|
|
126
|
+
gap: var(--s-2);
|
|
127
|
+
color: var(--ink-3);
|
|
128
|
+
font-size: var(--fs-cap);
|
|
129
|
+
font-weight: 500;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.live__dot {
|
|
133
|
+
width: 8px;
|
|
134
|
+
height: 8px;
|
|
135
|
+
border-radius: 50%;
|
|
136
|
+
background: var(--neutral);
|
|
137
|
+
flex: none;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.live--live .live__dot, .live--fixtures .live__dot {
|
|
141
|
+
background: var(--accent);
|
|
142
|
+
box-shadow: 0 0 0 3px var(--accent-wash);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.live--live .live__dot { animation: pulse 2.4s ease-in-out infinite; }
|
|
146
|
+
.live--offline .live__dot { background: var(--bad); }
|
|
147
|
+
|
|
148
|
+
@keyframes pulse {
|
|
149
|
+
0%, 100% { opacity: 1; transform: scale(1); }
|
|
150
|
+
50% { opacity: 0.55; transform: scale(0.85); }
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.filters {
|
|
154
|
+
display: flex;
|
|
155
|
+
flex-wrap: wrap;
|
|
156
|
+
align-items: center;
|
|
157
|
+
gap: var(--s-2);
|
|
158
|
+
margin-inline-start: auto;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.chip {
|
|
162
|
+
display: inline-flex;
|
|
163
|
+
align-items: center;
|
|
164
|
+
gap: var(--s-1);
|
|
165
|
+
height: 26px;
|
|
166
|
+
padding: 0 var(--s-1) 0 var(--s-2);
|
|
167
|
+
border: 1px solid var(--line);
|
|
168
|
+
border-radius: var(--r-full);
|
|
169
|
+
background: var(--surface);
|
|
170
|
+
font-size: var(--fs-cap);
|
|
171
|
+
max-width: 100%;
|
|
172
|
+
transition: border-color var(--t-micro);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.chip:hover { border-color: var(--line-2); }
|
|
176
|
+
.chip__k { color: var(--ink-3); }
|
|
177
|
+
|
|
178
|
+
.chip__v {
|
|
179
|
+
color: var(--ink);
|
|
180
|
+
font-weight: 500;
|
|
181
|
+
max-width: 22ch;
|
|
182
|
+
overflow: hidden;
|
|
183
|
+
text-overflow: ellipsis;
|
|
184
|
+
white-space: nowrap;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.chip__x {
|
|
188
|
+
width: 18px;
|
|
189
|
+
height: 18px;
|
|
190
|
+
border: 0;
|
|
191
|
+
border-radius: 50%;
|
|
192
|
+
background: transparent;
|
|
193
|
+
color: var(--ink-3);
|
|
194
|
+
cursor: pointer;
|
|
195
|
+
line-height: 1;
|
|
196
|
+
display: grid;
|
|
197
|
+
place-items: center;
|
|
198
|
+
transition: background-color var(--t-micro), color var(--t-micro);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.chip__x:hover { background: var(--wash-2); color: var(--ink); }
|
|
202
|
+
|
|
203
|
+
.tabs {
|
|
204
|
+
display: flex;
|
|
205
|
+
gap: var(--s-1);
|
|
206
|
+
padding-block: var(--s-1) var(--s-2);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.tab {
|
|
210
|
+
display: inline-flex;
|
|
211
|
+
align-items: center;
|
|
212
|
+
min-height: 36px;
|
|
213
|
+
padding: 0 var(--s-3);
|
|
214
|
+
border-radius: var(--r-sm);
|
|
215
|
+
color: var(--ink-2);
|
|
216
|
+
font-size: var(--fs-sm);
|
|
217
|
+
font-weight: 500;
|
|
218
|
+
text-decoration: none;
|
|
219
|
+
transition: background-color var(--t-micro), color var(--t-micro);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.tab:hover { background: var(--wash); color: var(--ink); }
|
|
223
|
+
.tab[aria-current="page"] { background: var(--wash-2); color: var(--ink); }
|
|
224
|
+
|
|
225
|
+
.page { padding-block: var(--s-5) var(--s-12); }
|
|
226
|
+
|
|
227
|
+
.btn {
|
|
228
|
+
display: inline-flex;
|
|
229
|
+
align-items: center;
|
|
230
|
+
gap: var(--s-2);
|
|
231
|
+
height: 32px;
|
|
232
|
+
padding: 0 var(--s-3);
|
|
233
|
+
border: 1px solid var(--line-2);
|
|
234
|
+
border-radius: var(--r-sm);
|
|
235
|
+
background: transparent;
|
|
236
|
+
color: var(--ink);
|
|
237
|
+
font-size: var(--fs-sm);
|
|
238
|
+
font-weight: 500;
|
|
239
|
+
cursor: pointer;
|
|
240
|
+
transition: background-color var(--t-micro), transform var(--t-micro);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.btn:hover { background: var(--wash); }
|
|
244
|
+
.btn:active { background: var(--wash-2); transform: translateY(1px); }
|
|
245
|
+
|
|
246
|
+
.toolbar {
|
|
247
|
+
display: flex;
|
|
248
|
+
flex-wrap: wrap;
|
|
249
|
+
align-items: center;
|
|
250
|
+
gap: var(--s-2);
|
|
251
|
+
margin-bottom: var(--s-3);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.field {
|
|
255
|
+
height: 32px;
|
|
256
|
+
padding: 0 var(--s-3);
|
|
257
|
+
border: 1px solid var(--line-2);
|
|
258
|
+
border-radius: var(--r-sm);
|
|
259
|
+
background: var(--surface);
|
|
260
|
+
color: var(--ink);
|
|
261
|
+
font-size: var(--fs-sm);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.field::placeholder { color: var(--ink-3); }
|
|
265
|
+
.field--search { flex: 1 1 14rem; min-width: 0; }
|
|
266
|
+
.field--select { padding-inline-end: var(--s-2); }
|
|
267
|
+
|
|
268
|
+
.toolbar__count {
|
|
269
|
+
color: var(--ink-3);
|
|
270
|
+
font-size: var(--fs-cap);
|
|
271
|
+
margin-inline-start: auto;
|
|
272
|
+
font-variant-numeric: tabular-nums;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.card {
|
|
276
|
+
background: var(--surface);
|
|
277
|
+
border: 1px solid var(--line);
|
|
278
|
+
border-radius: var(--r-md);
|
|
279
|
+
overflow: hidden;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.sessions {
|
|
283
|
+
width: 100%;
|
|
284
|
+
border-collapse: collapse;
|
|
285
|
+
table-layout: fixed;
|
|
286
|
+
font-size: var(--fs-sm);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.sessions th {
|
|
290
|
+
text-align: left;
|
|
291
|
+
padding: var(--s-2) var(--s-3);
|
|
292
|
+
color: var(--ink-3);
|
|
293
|
+
font-size: var(--fs-cap);
|
|
294
|
+
font-weight: 500;
|
|
295
|
+
border-bottom: 1px solid var(--line);
|
|
296
|
+
white-space: nowrap;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.sessions td {
|
|
300
|
+
padding: var(--s-3);
|
|
301
|
+
vertical-align: top;
|
|
302
|
+
border-bottom: 1px solid var(--line);
|
|
303
|
+
overflow-wrap: normal;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.sessions td.c-prompt { overflow-wrap: anywhere; }
|
|
307
|
+
|
|
308
|
+
.sessions tbody tr { transition: background-color var(--t-micro); cursor: pointer; }
|
|
309
|
+
.sessions tbody tr:last-child td { border-bottom: 0; }
|
|
310
|
+
.sessions tbody tr:hover, .sessions tbody tr:has(.rowlink:focus-visible) { background: var(--wash); }
|
|
311
|
+
|
|
312
|
+
.rowlink {
|
|
313
|
+
display: -webkit-box;
|
|
314
|
+
-webkit-box-orient: vertical;
|
|
315
|
+
-webkit-line-clamp: 2;
|
|
316
|
+
overflow: hidden;
|
|
317
|
+
color: var(--ink);
|
|
318
|
+
text-decoration: none;
|
|
319
|
+
line-height: 1.45;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.rowlink:hover { color: var(--ink); }
|
|
323
|
+
.rowlink--dim { color: var(--ink-3); font-style: italic; }
|
|
324
|
+
|
|
325
|
+
.rt { display: inline-flex; align-items: center; gap: var(--s-2); color: var(--ink); font-weight: 500; }
|
|
326
|
+
|
|
327
|
+
.rt__mark {
|
|
328
|
+
width: 24px;
|
|
329
|
+
height: 24px;
|
|
330
|
+
flex: none;
|
|
331
|
+
display: grid;
|
|
332
|
+
place-items: center;
|
|
333
|
+
border: 1px solid var(--line);
|
|
334
|
+
border-radius: var(--r-sm);
|
|
335
|
+
background: var(--surface-2);
|
|
336
|
+
color: var(--ink-2);
|
|
337
|
+
font: 600 var(--fs-micro) / 1 var(--font-mono);
|
|
338
|
+
letter-spacing: 0.02em;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.when { display: flex; flex-direction: column; color: var(--ink-2); font-variant-numeric: tabular-nums; line-height: 1.4; white-space: nowrap; }
|
|
342
|
+
.when__time { color: var(--ink); }
|
|
343
|
+
.when__dur { color: var(--ink-3); font-size: var(--fs-cap); }
|
|
344
|
+
|
|
345
|
+
.skills { display: flex; flex-wrap: wrap; gap: var(--s-1); }
|
|
346
|
+
|
|
347
|
+
.skill {
|
|
348
|
+
display: inline-flex;
|
|
349
|
+
align-items: center;
|
|
350
|
+
height: 22px;
|
|
351
|
+
padding: 0 var(--s-2);
|
|
352
|
+
border: 1px solid var(--line);
|
|
353
|
+
border-radius: var(--r-full);
|
|
354
|
+
color: var(--ink-2);
|
|
355
|
+
font-size: var(--fs-cap);
|
|
356
|
+
font-weight: 500;
|
|
357
|
+
max-width: 100%;
|
|
358
|
+
overflow: hidden;
|
|
359
|
+
text-overflow: ellipsis;
|
|
360
|
+
white-space: nowrap;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
.skill--more { color: var(--ink-3); }
|
|
364
|
+
.skills__none { color: var(--ink-3); font-size: var(--fs-cap); }
|
|
365
|
+
|
|
366
|
+
.badge {
|
|
367
|
+
display: inline-flex;
|
|
368
|
+
align-items: center;
|
|
369
|
+
gap: 6px;
|
|
370
|
+
height: 22px;
|
|
371
|
+
padding: 0 var(--s-2);
|
|
372
|
+
border-radius: var(--r-full);
|
|
373
|
+
background: color-mix(in srgb, var(--badge-c) 12%, transparent);
|
|
374
|
+
color: var(--ink-2);
|
|
375
|
+
font-size: var(--fs-cap);
|
|
376
|
+
font-weight: 500;
|
|
377
|
+
white-space: nowrap;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--badge-c); flex: none; }
|
|
381
|
+
.badge--loaded { --badge-c: var(--ok); }
|
|
382
|
+
.badge--exposed_only { --badge-c: var(--warn); }
|
|
383
|
+
.badge--no_match { --badge-c: var(--bad); }
|
|
384
|
+
.badge--aborted, .badge--not_used { --badge-c: var(--neutral); }
|
|
385
|
+
|
|
386
|
+
.attr { color: var(--ink-2); font-size: var(--fs-cap); white-space: nowrap; }
|
|
387
|
+
.attr--none { color: var(--ink-3); }
|
|
388
|
+
|
|
389
|
+
[data-tip] { position: relative; }
|
|
390
|
+
|
|
391
|
+
[data-tip]::after {
|
|
392
|
+
content: attr(data-tip);
|
|
393
|
+
position: absolute;
|
|
394
|
+
left: 0;
|
|
395
|
+
bottom: calc(100% + 6px);
|
|
396
|
+
z-index: 2;
|
|
397
|
+
padding: var(--s-1) var(--s-2);
|
|
398
|
+
border-radius: var(--r-sm);
|
|
399
|
+
background: var(--ink);
|
|
400
|
+
color: var(--bg);
|
|
401
|
+
font-size: var(--fs-cap);
|
|
402
|
+
font-weight: 500;
|
|
403
|
+
line-height: 1.4;
|
|
404
|
+
white-space: nowrap;
|
|
405
|
+
box-shadow: var(--shadow-pop);
|
|
406
|
+
opacity: 0;
|
|
407
|
+
transform: translateY(2px);
|
|
408
|
+
pointer-events: none;
|
|
409
|
+
transition: opacity var(--t-micro), transform var(--t-micro);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
[data-tip]:hover::after, [data-tip]:focus-visible::after { opacity: 1; transform: none; }
|
|
413
|
+
.c-attr [data-tip]::after { left: auto; right: 0; }
|
|
414
|
+
|
|
415
|
+
.empty {
|
|
416
|
+
max-width: 48ch;
|
|
417
|
+
margin: var(--s-12) auto;
|
|
418
|
+
padding: var(--s-8) var(--s-4);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.empty h2 { margin: 0 0 var(--s-2); font-size: var(--fs-title); font-weight: 600; letter-spacing: -0.01em; }
|
|
422
|
+
.empty p { margin: 0 0 var(--s-4); color: var(--ink-2); }
|
|
423
|
+
|
|
424
|
+
.checklist {
|
|
425
|
+
display: grid;
|
|
426
|
+
grid-template-columns: max-content 1fr;
|
|
427
|
+
gap: var(--s-1) var(--s-4);
|
|
428
|
+
margin: 0 0 var(--s-4);
|
|
429
|
+
font-size: var(--fs-sm);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
.checklist dt { color: var(--ink-2); }
|
|
433
|
+
.checklist dd { margin: 0; color: var(--ink-3); font-variant-numeric: tabular-nums; }
|
|
434
|
+
.checklist dd.is-ok { color: var(--ink); }
|
|
435
|
+
.checklist dd.is-bad { color: var(--bad); }
|
|
436
|
+
|
|
437
|
+
.cmd {
|
|
438
|
+
font-family: var(--font-mono);
|
|
439
|
+
font-size: var(--fs-sm);
|
|
440
|
+
padding: 2px var(--s-2);
|
|
441
|
+
border-radius: var(--r-sm);
|
|
442
|
+
background: var(--surface-2);
|
|
443
|
+
border: 1px solid var(--line);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.notice { color: var(--bad); font-size: var(--fs-sm); margin-bottom: var(--s-3); }
|
|
447
|
+
|
|
448
|
+
@media (min-width: 640px) and (max-width: 959.98px) {
|
|
449
|
+
.sessions { table-layout: auto; }
|
|
450
|
+
.sessions col { width: auto !important; }
|
|
451
|
+
.sessions th, .sessions td { padding-inline: var(--s-2); }
|
|
452
|
+
.sessions td.c-prompt { min-width: 11rem; }
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
@media (max-width: 639.98px) {
|
|
456
|
+
.sessions, .sessions tbody, .sessions tr, .sessions td { display: block; }
|
|
457
|
+
.sessions colgroup, .sessions thead { display: none; }
|
|
458
|
+
|
|
459
|
+
.sessions tr {
|
|
460
|
+
display: grid;
|
|
461
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
462
|
+
grid-template-areas:
|
|
463
|
+
"runtime started"
|
|
464
|
+
"prompt prompt"
|
|
465
|
+
"skills skills"
|
|
466
|
+
"state attr";
|
|
467
|
+
gap: var(--s-2) var(--s-3);
|
|
468
|
+
padding: var(--s-3) var(--s-4);
|
|
469
|
+
border-bottom: 1px solid var(--line);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
.sessions tbody tr:last-child { border-bottom: 0; }
|
|
473
|
+
.sessions td { padding: 0; border: 0; min-width: 0; }
|
|
474
|
+
.c-runtime { grid-area: runtime; }
|
|
475
|
+
.c-started { grid-area: started; justify-self: end; }
|
|
476
|
+
.c-prompt { grid-area: prompt; }
|
|
477
|
+
.c-skills { grid-area: skills; }
|
|
478
|
+
.c-state { grid-area: state; }
|
|
479
|
+
.c-attr { grid-area: attr; justify-self: end; }
|
|
480
|
+
.when { flex-direction: row; gap: var(--s-2); }
|
|
481
|
+
.when__dur::before { content: "\00b7\00a0"; }
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
@media (prefers-reduced-motion: reduce) {
|
|
485
|
+
.live__dot { animation: none; }
|
|
486
|
+
*, *::before, *::after { transition: none !important; }
|
|
487
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<meta name="color-scheme" content="light dark" />
|
|
7
|
+
<meta name="referrer" content="no-referrer" />
|
|
8
|
+
<title>gisool</title>
|
|
9
|
+
<link rel="stylesheet" href="assets/styles.css" />
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div id="app"></div>
|
|
13
|
+
<script type="module" src="assets/app.js"></script>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export const WINDOW_MS = 120_000;
|
|
2
|
+
const MAX_TRACKED = 10_000;
|
|
3
|
+
export function createAttributionState() {
|
|
4
|
+
return { toolUseSessions: new Map(), loadSessions: new Map() };
|
|
5
|
+
}
|
|
6
|
+
export function remember(map, key, value) {
|
|
7
|
+
map.delete(key);
|
|
8
|
+
map.set(key, value);
|
|
9
|
+
if (map.size > MAX_TRACKED) {
|
|
10
|
+
const oldest = map.keys().next().value;
|
|
11
|
+
if (oldest !== undefined)
|
|
12
|
+
map.delete(oldest);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function attributed(sessionId) {
|
|
16
|
+
return sessionId !== undefined && sessionId !== "unattributed";
|
|
17
|
+
}
|
|
18
|
+
export function attribute(event, store, now, state = createAttributionState()) {
|
|
19
|
+
const { ref } = event;
|
|
20
|
+
const hasRuntimeKey = Boolean(ref.runtimeSessionId || ref.conversationId);
|
|
21
|
+
// (1) hook / OTel events carry the runtime's own session id.
|
|
22
|
+
if (event.source !== "mcp" && hasRuntimeKey) {
|
|
23
|
+
return { sessionId: store.upsertSession(ref, event.ts), method: "runtime_id" };
|
|
24
|
+
}
|
|
25
|
+
// (2) MCP events: vendor _meta session ids, or a Claude tool_use_id already bound by a PostToolUse hook.
|
|
26
|
+
if (event.source === "mcp") {
|
|
27
|
+
if (hasRuntimeKey)
|
|
28
|
+
return { sessionId: store.upsertSession(ref, event.ts), method: "vendor_meta" };
|
|
29
|
+
const bound = event.toolUseId ? state.toolUseSessions.get(event.toolUseId) : undefined;
|
|
30
|
+
if (bound)
|
|
31
|
+
return { sessionId: bound, method: "vendor_meta" };
|
|
32
|
+
}
|
|
33
|
+
// (3) load / read_file joined to an attributed search (traceId) or load (loadId).
|
|
34
|
+
if (event.kind === "load" || event.kind === "read_file") {
|
|
35
|
+
const viaTrace = event.traceId ? store.traceSession(event.traceId) : undefined;
|
|
36
|
+
if (attributed(viaTrace))
|
|
37
|
+
return { sessionId: viaTrace, method: "trace_handle" };
|
|
38
|
+
const viaLoad = event.loadId ? state.loadSessions.get(event.loadId) : undefined;
|
|
39
|
+
if (attributed(viaLoad))
|
|
40
|
+
return { sessionId: viaLoad, method: "trace_handle" };
|
|
41
|
+
}
|
|
42
|
+
// (4) exactly one open session of the same runtime active within the window; never across runtimes.
|
|
43
|
+
if (ref.runtime === "unknown")
|
|
44
|
+
return { sessionId: "unattributed", method: "none", reason: "no_session" };
|
|
45
|
+
const open = store.openSessions(ref.runtime, 0).filter((s) => s.ref.runtime === ref.runtime);
|
|
46
|
+
const fresh = open.filter((s) => now - s.lastActivityAt <= WINDOW_MS);
|
|
47
|
+
if (fresh.length === 1)
|
|
48
|
+
return { sessionId: fresh[0].id, method: "window" };
|
|
49
|
+
// (5) unattributed with the reason the window could not decide.
|
|
50
|
+
if (fresh.length > 1)
|
|
51
|
+
return { sessionId: "unattributed", method: "none", reason: "ambiguous" };
|
|
52
|
+
if (open.length > 0)
|
|
53
|
+
return { sessionId: "unattributed", method: "none", reason: "stale" };
|
|
54
|
+
return { sessionId: "unattributed", method: "none", reason: "no_session" };
|
|
55
|
+
}
|