openwolf-enhanced 1.20.9 → 1.21.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/dist/dashboard/assets/{AISuggestions-0zrodHvB.js → AISuggestions-C9y4DXN7.js} +1 -1
- package/dist/dashboard/assets/{ActivityLog-DYEe6Mh-.js → ActivityLog-BwI3hu53.js} +1 -1
- package/dist/dashboard/assets/{ActivityTimeline-BPomzQWf.js → ActivityTimeline-CxfgPqU7.js} +1 -1
- package/dist/dashboard/assets/{AnatomyBrowser-D3m69d-p.js → AnatomyBrowser-6xUbPIvg.js} +1 -1
- package/dist/dashboard/assets/{BugLog-C44GE8m7.js → BugLog-D-bqCcdb.js} +1 -1
- package/dist/dashboard/assets/{CerebrumViewer-CxvLTVFs.js → CerebrumViewer-Di01VvRz.js} +1 -1
- package/dist/dashboard/assets/{CronStatus-DCiCUVLZ.js → CronStatus-0LpbP4Gk.js} +1 -1
- package/dist/dashboard/assets/{DesignQC-w7X5uW1P.js → DesignQC-x5mYKkE4.js} +1 -1
- package/dist/dashboard/assets/{MemoryViewer-CraLooQx.js → MemoryViewer-Bc4Vw64G.js} +1 -1
- package/dist/dashboard/assets/{NativeMemory-CaYixCd2.js → NativeMemory-Dkk5zZei.js} +1 -1
- package/dist/dashboard/assets/{ProjectOverview-DJacADHV.js → ProjectOverview-C7G8tn04.js} +1 -1
- package/dist/dashboard/assets/{ProjectsAggregate-xpOM2n6T.js → ProjectsAggregate-Vu_cGEVx.js} +1 -1
- package/dist/dashboard/assets/{StatusBadge-CzoOrUrs.js → StatusBadge-D6b5MXQJ.js} +1 -1
- package/dist/dashboard/assets/{TokenUsage-BUL-gsby.js → TokenUsage-DFc8Ut2I.js} +2 -2
- package/dist/dashboard/assets/{index-BZOA5m43.js → index-BxheJgWu.js} +3 -3
- package/dist/dashboard/assets/index-CbZ7BrXr.css +2 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/hooks/session-start.js +4 -1
- package/dist/hooks/shared.js +60 -0
- package/dist/hooks/stop.js +5 -1
- package/dist/src/cli/find-cmd.js +163 -0
- package/dist/src/cli/find-cmd.js.map +1 -0
- package/dist/src/cli/index.js +10 -0
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/report-cmd.js +20 -1
- package/dist/src/cli/report-cmd.js.map +1 -1
- package/dist/src/cli/scan.js +31 -0
- package/dist/src/cli/scan.js.map +1 -1
- package/dist/src/cli/status.js +4 -1
- package/dist/src/cli/status.js.map +1 -1
- package/dist/src/hooks/session-start.js +4 -1
- package/dist/src/hooks/session-start.js.map +1 -1
- package/dist/src/hooks/shared.js +60 -0
- package/dist/src/hooks/shared.js.map +1 -1
- package/dist/src/hooks/stop.js +5 -1
- package/dist/src/hooks/stop.js.map +1 -1
- package/dist/src/mcp/server.js +32 -0
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/scanner/anatomy-scanner.js +29 -5
- package/dist/src/scanner/anatomy-scanner.js.map +1 -1
- package/dist/src/scanner/import-graph.js +206 -0
- package/dist/src/scanner/import-graph.js.map +1 -0
- package/dist/src/scanner/treesitter-extractor.js +226 -0
- package/dist/src/scanner/treesitter-extractor.js.map +1 -0
- package/dist/src/tracker/token-ledger.js +1 -0
- package/dist/src/tracker/token-ledger.js.map +1 -1
- package/dist/src/utils/agent-hooks.js +73 -9
- package/dist/src/utils/agent-hooks.js.map +1 -1
- package/dist/src/utils/marker-block.js +68 -0
- package/dist/src/utils/marker-block.js.map +1 -0
- package/package.json +4 -2
- package/dist/dashboard/assets/index-Cr3yWM5G.css +0 -2
|
@@ -2,6 +2,7 @@ import * as fs from "node:fs";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { readJSON, writeJSON, writeText } from "./fs-safe.js";
|
|
4
4
|
import { ensureDir } from "./paths.js";
|
|
5
|
+
import { upsertMarkerBlock, AGENTS_SNIPPET } from "./marker-block.js";
|
|
5
6
|
export const NON_CLAUDE_AGENTS = ["codex", "gemini", "opencode"];
|
|
6
7
|
const HOOKS = [
|
|
7
8
|
{ script: "session-start.js", claudeEvent: "SessionStart", matcher: "" },
|
|
@@ -43,19 +44,69 @@ function claudeSettings() {
|
|
|
43
44
|
// ---- Codex: same event names as Claude; edits arrive as `apply_patch`, shell as `Bash`.
|
|
44
45
|
// Env var for the project dir is unconfirmed upstream, so we bake in the absolute path (stable per
|
|
45
46
|
// machine → the trust-hash stays put until the next `openwolf update`). ----
|
|
47
|
+
// [2026-08-20] Codex used to get only 4 of the 8 hooks: session-start, post-write, post-bash,
|
|
48
|
+
// stop. Missing were pre-read, pre-write, post-read and precompact — exactly the ones carrying
|
|
49
|
+
// read avoidance, the do-not-repeat warning and the compaction snapshot. OpenWolf ran on Codex
|
|
50
|
+
// at half strength without anything ever failing.
|
|
51
|
+
//
|
|
52
|
+
// Matchers are a UNION of Claude and Codex tool names: which name Codex actually sends depends
|
|
53
|
+
// on its version, and a matcher that misses fails silently. The earlier `^apply_patch$` would
|
|
54
|
+
// never have seen a write reported as `Write`. `statusMessage` is Codex-specific and shows there
|
|
55
|
+
// what is currently running.
|
|
46
56
|
function codexSettings(projectRoot) {
|
|
47
|
-
const c = (script
|
|
57
|
+
const c = (script, statusMessage, timeout = 15) => ({
|
|
58
|
+
type: "command", _managedBy: "openwolf", statusMessage,
|
|
59
|
+
command: cmd(projectRoot, script, { literal: true, exportVar: true }), timeout,
|
|
60
|
+
});
|
|
61
|
+
const WRITE = "^(Edit|Write|MultiEdit|apply_patch)$";
|
|
62
|
+
const READ = "^(Read|read_file)$";
|
|
48
63
|
return {
|
|
49
64
|
hooks: {
|
|
50
|
-
|
|
65
|
+
// [2026-08-20, review] NO matcher here on purpose. `startup|resume|clear` omits `compact`,
|
|
66
|
+
// and session-start.ts has a dedicated branch for source === "compact" that re-injects the
|
|
67
|
+
// post-compaction digest — which this same change newly makes reachable by deploying
|
|
68
|
+
// PreCompact to Codex. Claude's entry matches every source too (matcher: "").
|
|
69
|
+
SessionStart: [{ hooks: [c("session-start.js", "OpenWolf session bootstrap")] }],
|
|
70
|
+
PreToolUse: [
|
|
71
|
+
{ matcher: READ, hooks: [c("pre-read.js", "OpenWolf read precheck")] },
|
|
72
|
+
{ matcher: WRITE, hooks: [c("pre-write.js", "OpenWolf write precheck")] },
|
|
73
|
+
],
|
|
51
74
|
PostToolUse: [
|
|
52
|
-
{ matcher:
|
|
53
|
-
{ matcher:
|
|
75
|
+
{ matcher: READ, hooks: [c("post-read.js", "OpenWolf read tracking")] },
|
|
76
|
+
{ matcher: WRITE, hooks: [c("post-write.js", "OpenWolf anatomy update", 20)] },
|
|
77
|
+
{ matcher: "^(Bash|shell|local_shell)$", hooks: [c("post-bash.js", "OpenWolf shell tracking")] },
|
|
54
78
|
],
|
|
55
|
-
|
|
79
|
+
PreCompact: [{ hooks: [c("precompact.js", "OpenWolf compaction snapshot")] }],
|
|
80
|
+
Stop: [{ hooks: [c("stop.js", "OpenWolf session wrap-up", 20)] }],
|
|
56
81
|
},
|
|
57
82
|
};
|
|
58
83
|
}
|
|
84
|
+
// Codex only reads hooks when `hooks = true` sits under `[features]`. Without that switch a
|
|
85
|
+
// perfectly fine-looking hooks.json is there and none of it fires — so we create the file when it
|
|
86
|
+
// is missing and WARN otherwise, rather than editing someone else's config.toml.
|
|
87
|
+
function ensureCodexFeatureFlag(codexDir) {
|
|
88
|
+
const p = path.join(codexDir, "config.toml");
|
|
89
|
+
if (!fs.existsSync(p)) {
|
|
90
|
+
writeText(p, "[features]\nhooks = true\n");
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
const existing = fs.readFileSync(p, "utf-8");
|
|
94
|
+
// Anchored AND table-scoped. [2026-08-20, review] Anchoring alone still accepted `hooks = true`
|
|
95
|
+
// under any other table (e.g. `[experimental]`), where Codex ignores it — the warning would be
|
|
96
|
+
// swallowed while the hooks stayed dead. So: find [features] and look only until the next table.
|
|
97
|
+
const lines = existing.split(/\r?\n/);
|
|
98
|
+
let inFeatures = false;
|
|
99
|
+
for (const line of lines) {
|
|
100
|
+
const table = line.match(/^\s*\[([^\]]+)\]\s*$/);
|
|
101
|
+
if (table) {
|
|
102
|
+
inFeatures = table[1].trim() === "features";
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (inFeatures && /^\s*hooks\s*=\s*true\s*$/.test(line))
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
return 'set "hooks = true" under [features] in .codex/config.toml — otherwise Codex ignores the hooks';
|
|
109
|
+
}
|
|
59
110
|
// ---- Gemini: PostToolUse = AfterTool, Stop = SessionEnd; tools write_file/replace/run_shell_command.
|
|
60
111
|
// $GEMINI_PROJECT_DIR is documented. Timeouts are milliseconds here. ----
|
|
61
112
|
function geminiSettings() {
|
|
@@ -150,8 +201,18 @@ export function deployAgentHooks(projectRoot) {
|
|
|
150
201
|
for (const agent of detectAgents(projectRoot)) {
|
|
151
202
|
try {
|
|
152
203
|
if (agent === "codex") {
|
|
153
|
-
|
|
154
|
-
|
|
204
|
+
const codexDir = path.join(projectRoot, ".codex");
|
|
205
|
+
deployJsonAgent(codexDir, "hooks.json", codexSettings(projectRoot));
|
|
206
|
+
const warn = ensureCodexFeatureFlag(codexDir);
|
|
207
|
+
const ctx = upsertMarkerBlock(path.join(projectRoot, "AGENTS.md"), AGENTS_SNIPPET);
|
|
208
|
+
const bits = [".codex/hooks.json (re-approve trust in Codex)"];
|
|
209
|
+
if (ctx.changed)
|
|
210
|
+
bits.push("AGENTS.md block");
|
|
211
|
+
if (ctx.refused)
|
|
212
|
+
bits.push(`AGENTS.md skipped: ${ctx.refused}`);
|
|
213
|
+
if (warn)
|
|
214
|
+
bits.push(`⚠ ${warn}`);
|
|
215
|
+
results.push({ agent, deployed: true, detail: bits.join(" · ") });
|
|
155
216
|
}
|
|
156
217
|
else if (agent === "gemini") {
|
|
157
218
|
deployJsonAgent(path.join(projectRoot, ".gemini"), "settings.json", geminiSettings());
|
|
@@ -161,7 +222,10 @@ export function deployAgentHooks(projectRoot) {
|
|
|
161
222
|
const dir = path.join(projectRoot, ".opencode", "plugin");
|
|
162
223
|
ensureDir(dir);
|
|
163
224
|
writeText(path.join(dir, "openwolf.js"), opencodePlugin(projectRoot));
|
|
164
|
-
|
|
225
|
+
// OpenCode reads AGENTS.md as its context file — without the block it never sees the protocol.
|
|
226
|
+
const ctx = upsertMarkerBlock(path.join(projectRoot, "AGENTS.md"), AGENTS_SNIPPET);
|
|
227
|
+
results.push({ agent, deployed: true, detail: ".opencode/plugin/openwolf.js (compaction-only inject)"
|
|
228
|
+
+ (ctx.changed ? " · AGENTS.md block" : "") + (ctx.refused ? ` · AGENTS.md skipped: ${ctx.refused}` : "") });
|
|
165
229
|
}
|
|
166
230
|
}
|
|
167
231
|
catch (e) {
|
|
@@ -171,5 +235,5 @@ export function deployAgentHooks(projectRoot) {
|
|
|
171
235
|
return results;
|
|
172
236
|
}
|
|
173
237
|
// Exposed for tests.
|
|
174
|
-
export const _internal = { claudeSettings, codexSettings, geminiSettings, opencodePlugin, mergeManagedHooks };
|
|
238
|
+
export const _internal = { claudeSettings, codexSettings, geminiSettings, opencodePlugin, mergeManagedHooks, ensureCodexFeatureFlag };
|
|
175
239
|
//# sourceMappingURL=agent-hooks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-hooks.js","sourceRoot":"","sources":["../../../src/utils/agent-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-hooks.js","sourceRoot":"","sources":["../../../src/utils/agent-hooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import { writeText } from "./fs-safe.js";
|
|
3
|
+
// [2026-08-20] Context files belonging to other harnesses (AGENTS.md for Codex and OpenCode,
|
|
4
|
+
// GEMINI.md for Gemini CLI) are the user's. OpenWolf manages exactly one delimited block inside
|
|
5
|
+
// them and leaves everything outside it byte for byte alone.
|
|
6
|
+
//
|
|
7
|
+
// Before this, our fork did not write these files AT ALL: on Codex our hooks fired, but the
|
|
8
|
+
// protocol never reached the model — it reads AGENTS.md, not CLAUDE.md.
|
|
9
|
+
export const MARKER_BEGIN = "<!-- openwolf:begin -->";
|
|
10
|
+
export const MARKER_END = "<!-- openwolf:end -->";
|
|
11
|
+
/**
|
|
12
|
+
* Insert or replace the OpenWolf block in a markdown context file.
|
|
13
|
+
*
|
|
14
|
+
* Rules that matter more here than convenience:
|
|
15
|
+
* - Everything outside the markers stays untouched. That is user content.
|
|
16
|
+
* - With no markers present, the block is prepended (the way init.ts handles CLAUDE.md) and the
|
|
17
|
+
* existing text is preserved below it.
|
|
18
|
+
* - If the markers are broken (END before BEGIN, or BEGIN without END), NOTHING is written and
|
|
19
|
+
* the reason is returned. Repairing a half-written foreign file is more dangerous than leaving
|
|
20
|
+
* it alone.
|
|
21
|
+
*/
|
|
22
|
+
export function upsertMarkerBlock(filePath, content) {
|
|
23
|
+
const block = `${MARKER_BEGIN}\n${content.trim()}\n${MARKER_END}`;
|
|
24
|
+
let existing = "";
|
|
25
|
+
try {
|
|
26
|
+
existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, "utf-8") : "";
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
return { changed: false, refused: `not readable: ${e.message}` };
|
|
30
|
+
}
|
|
31
|
+
if (existing === "") {
|
|
32
|
+
return { changed: writeText(filePath, block + "\n") };
|
|
33
|
+
}
|
|
34
|
+
const b = existing.indexOf(MARKER_BEGIN);
|
|
35
|
+
const e = existing.indexOf(MARKER_END);
|
|
36
|
+
if (b === -1 && e === -1) {
|
|
37
|
+
const next = `${block}\n\n${existing.replace(/^\n+/, "")}`;
|
|
38
|
+
return next === existing ? { changed: false } : { changed: writeText(filePath, next) };
|
|
39
|
+
}
|
|
40
|
+
if (b === -1 || e === -1 || e < b) {
|
|
41
|
+
return {
|
|
42
|
+
changed: false,
|
|
43
|
+
refused: "markers incomplete or swapped — file left untouched",
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const next = existing.slice(0, b) + block + existing.slice(e + MARKER_END.length);
|
|
47
|
+
return next === existing ? { changed: false } : { changed: writeText(filePath, next) };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The protocol text for non-Claude harnesses. Deliberately WITHOUT Claude's `@file` include:
|
|
51
|
+
* Codex does not understand it, and a reference that silently does nothing is worse than an
|
|
52
|
+
* instruction to read the file.
|
|
53
|
+
*/
|
|
54
|
+
export const AGENTS_SNIPPET = `## OpenWolf
|
|
55
|
+
|
|
56
|
+
This project uses OpenWolf for context management. Its knowledge lives in \`.wolf/\`.
|
|
57
|
+
|
|
58
|
+
1. **Read \`.wolf/STATUS.md\` first** — current quest, open points, decisions.
|
|
59
|
+
2. **Check \`.wolf/anatomy.md\` before opening any file.** If the description there answers
|
|
60
|
+
your question, do not read the file.
|
|
61
|
+
3. **Read \`.wolf/cerebrum.md\` before generating code** — especially \`## Do-Not-Repeat\`.
|
|
62
|
+
4. **Check \`.wolf/buglog.json\` before fixing an error** — the fix may already be known.
|
|
63
|
+
5. **After significant actions**, append one line to \`.wolf/memory.md\`; after adding,
|
|
64
|
+
deleting or renaming files, update \`.wolf/anatomy.md\`.
|
|
65
|
+
|
|
66
|
+
Wrap anything secret in \`<private>…</private>\` — those blocks stay out of the resume
|
|
67
|
+
digest, out of \`openwolf recall\`, and out of anything OpenWolf sends elsewhere.`;
|
|
68
|
+
//# sourceMappingURL=marker-block.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marker-block.js","sourceRoot":"","sources":["../../../src/utils/marker-block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,6FAA6F;AAC7F,gGAAgG;AAChG,6DAA6D;AAC7D,EAAE;AACF,4FAA4F;AAC5F,wEAAwE;AAExE,MAAM,CAAC,MAAM,YAAY,GAAG,yBAAyB,CAAC;AACtD,MAAM,CAAC,MAAM,UAAU,GAAG,uBAAuB,CAAC;AASlD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,OAAe;IACjE,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,OAAO,CAAC,IAAI,EAAE,KAAK,UAAU,EAAE,CAAC;IAElE,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,IAAI,CAAC;QACH,QAAQ,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/E,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,iBAAkB,CAAW,CAAC,OAAO,EAAE,EAAE,CAAC;IAC9E,CAAC;IAED,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,QAAQ,EAAE,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAEvC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,GAAG,KAAK,OAAO,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;QAC3D,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC;IACzF,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,qDAAqD;SAC/D,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAClF,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC;AACzF,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;kFAaoD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openwolf-enhanced",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.21.0",
|
|
4
4
|
"description": "A second brain for Claude Code, Codex & Gemini — persistent git-native project memory with searchable citations, an MCP server for Claude Desktop, and invisible hook-based context. No database.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -29,7 +29,9 @@
|
|
|
29
29
|
"ws": "^8.21.0"
|
|
30
30
|
},
|
|
31
31
|
"optionalDependencies": {
|
|
32
|
-
"puppeteer-core": "^25.0.0"
|
|
32
|
+
"puppeteer-core": "^25.0.0",
|
|
33
|
+
"tree-sitter-wasms": "^0.1.13",
|
|
34
|
+
"web-tree-sitter": "^0.24.7"
|
|
33
35
|
},
|
|
34
36
|
"devDependencies": {
|
|
35
37
|
"@tailwindcss/vite": "^4.3.0",
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-zinc-400:oklch(70.5% .015 286.067);--color-zinc-500:oklch(55.2% .016 285.938);--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-lg:32rem;--container-3xl:48rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--font-weight-medium:500;--font-weight-bold:700;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:0}.top-0{top:0}.top-4{top:calc(var(--spacing) * 4)}.right-0{right:0}.right-4{right:calc(var(--spacing) * 4)}.bottom-0{bottom:0}.left-0{left:0}.z-50{z-index:50}.mx-1{margin-inline:var(--spacing)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mr-1\.5{margin-right:calc(var(--spacing) * 1.5)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-1{margin-bottom:var(--spacing)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-3{margin-left:calc(var(--spacing) * 3)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-24{height:calc(var(--spacing) * 24)}.h-40{height:calc(var(--spacing) * 40)}.h-screen{height:100vh}.max-h-\[80vh\]{max-height:80vh}.max-h-\[90vh\]{max-height:90vh}.min-h-screen{min-height:100vh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-9{width:calc(var(--spacing) * 9)}.w-12{width:calc(var(--spacing) * 12)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-48{width:calc(var(--spacing) * 48)}.w-60{width:calc(var(--spacing) * 60)}.w-full{width:100%}.max-w-3xl{max-width:var(--container-3xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-lg{max-width:var(--container-lg)}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:0}.min-w-48{min-width:calc(var(--spacing) * 48)}.min-w-\[64px\]{min-width:64px}.min-w-\[200px\]{min-width:200px}.flex-1{flex:1}.shrink-0{flex-shrink:0}.animate-pulse{animation:var(--animate-pulse)}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-amber-500\/30{border-color:#f99c004d}@supports (color:color-mix(in lab, red, red)){.border-amber-500\/30{border-color:color-mix(in oklab, var(--color-amber-500) 30%, transparent)}}.border-blue-500\/30{border-color:#3080ff4d}@supports (color:color-mix(in lab, red, red)){.border-blue-500\/30{border-color:color-mix(in oklab, var(--color-blue-500) 30%, transparent)}}.border-emerald-500\/30{border-color:#00bb7f4d}@supports (color:color-mix(in lab, red, red)){.border-emerald-500\/30{border-color:color-mix(in oklab, var(--color-emerald-500) 30%, transparent)}}.border-red-500\/30{border-color:#fb2c364d}@supports (color:color-mix(in lab, red, red)){.border-red-500\/30{border-color:color-mix(in oklab, var(--color-red-500) 30%, transparent)}}.border-zinc-500\/30{border-color:#71717b4d}@supports (color:color-mix(in lab, red, red)){.border-zinc-500\/30{border-color:color-mix(in oklab, var(--color-zinc-500) 30%, transparent)}}.bg-amber-500\/20{background-color:#f99c0033}@supports (color:color-mix(in lab, red, red)){.bg-amber-500\/20{background-color:color-mix(in oklab, var(--color-amber-500) 20%, transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-500\/20{background-color:#3080ff33}@supports (color:color-mix(in lab, red, red)){.bg-blue-500\/20{background-color:color-mix(in oklab, var(--color-blue-500) 20%, transparent)}}.bg-emerald-400{background-color:var(--color-emerald-400)}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-emerald-500\/20{background-color:#00bb7f33}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/20{background-color:color-mix(in oklab, var(--color-emerald-500) 20%, transparent)}}.bg-red-500\/20{background-color:#fb2c3633}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/20{background-color:color-mix(in oklab, var(--color-red-500) 20%, transparent)}}.bg-zinc-500{background-color:var(--color-zinc-500)}.bg-zinc-500\/20{background-color:#71717b33}@supports (color:color-mix(in lab, red, red)){.bg-zinc-500\/20{background-color:color-mix(in oklab, var(--color-zinc-500) 20%, transparent)}}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-16{padding-block:calc(var(--spacing) * 16)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-20{padding-bottom:calc(var(--spacing) * 20)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber-400{color:var(--color-amber-400)}.text-blue-400{color:var(--color-blue-400)}.text-emerald-400{color:var(--color-emerald-400)}.text-red-400{color:var(--color-red-400)}.text-zinc-400{color:var(--color-zinc-400)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.underline{text-decoration-line:underline}.decoration-dotted{text-decoration-style:dotted}.underline-offset-2{text-underline-offset:2px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}@media (hover:hover){.hover\:-translate-y-0\.5:hover{--tw-translate-y:calc(var(--spacing) * -.5);translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:bg-\(--bg-surface-hover\):hover{background-color:var(--bg-surface-hover)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}@media (width>=48rem){.md\:ml-60{margin-left:calc(var(--spacing) * 60)}.md\:flex{display:flex}.md\:hidden{display:none}.md\:table-cell{display:table-cell}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:pb-6{padding-bottom:calc(var(--spacing) * 6)}}}:root{--font-sans:"Inter", system-ui, -apple-system, sans-serif;--font-mono:"JetBrains Mono", monospace;--bg-base:#fff;--bg-surface:#f4f4f5;--bg-surface-hover:#e4e4e7;--bg-elevated:#fff;--border:#d4d4d8;--border-subtle:#e4e4e7;--text-primary:#09090b;--text-secondary:#3f3f46;--text-muted:#71717a;--text-faint:#a1a1aa;--accent:#059669;--accent-subtle:#0596691a;--danger:#dc2626;--danger-subtle:#dc26260d;--warning:#d97706;--warning-subtle:#d977060d;--scrollbar-track:#f4f4f5;--scrollbar-thumb:#d4d4d8;--scrollbar-thumb-hover:#a1a1aa;--chart-tooltip-bg:#fff;--chart-tooltip-border:#d4d4d8;--chart-grid:#e4e4e7}[data-theme=dark]{--bg-base:#09090b;--bg-surface:#18181b;--bg-surface-hover:#27272a;--bg-elevated:#18181b;--border:#27272a;--border-subtle:#3f3f46;--text-primary:#fafafa;--text-secondary:#a1a1aa;--text-muted:#71717a;--text-faint:#52525b;--accent:#34d399;--accent-subtle:#34d3991a;--danger:#f87171;--danger-subtle:#f871710d;--warning:#fbbf24;--warning-subtle:#fbbf240d;--scrollbar-track:#18181b;--scrollbar-thumb:#3f3f46;--scrollbar-thumb-hover:#52525b;--chart-tooltip-bg:#18181b;--chart-tooltip-border:#3f3f46;--chart-grid:#27272a}body{font-family:var(--font-sans);background:var(--bg-base);color:var(--text-primary);-webkit-font-smoothing:antialiased;margin:0;transition:background-color .2s,color .2s}code,pre,.font-mono{font-family:var(--font-mono)}*{box-sizing:border-box}::-webkit-scrollbar{width:8px}::-webkit-scrollbar-track{background:var(--scrollbar-track)}::-webkit-scrollbar-thumb{background:var(--scrollbar-thumb);border-radius:4px}::-webkit-scrollbar-thumb:hover{background:var(--scrollbar-thumb-hover)}@keyframes pulse-green{0%,to{opacity:1}50%{opacity:.5}}.pulse-green{animation:2s ease-in-out infinite pulse-green}.bg-base{background-color:var(--bg-base)}.bg-surface{background-color:var(--bg-surface)}.bg-elevated{background-color:var(--bg-elevated)}.border-theme{border-color:var(--border)}.border-subtle{border-color:var(--border-subtle)}.text-primary{color:var(--text-primary)}.text-secondary{color:var(--text-secondary)}.text-muted{color:var(--text-muted)}.text-faint{color:var(--text-faint)}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@keyframes pulse{50%{opacity:.5}}
|