@xelauvas/xela-cli 0.2.0 → 0.2.2
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/package.json +1 -1
- package/src/commands/init.ts +39 -39
- package/src/components/LogoV2/Clawd.tsx +27 -26
- package/src/components/Settings/Config.tsx +1 -1
- package/src/components/memory/MemoryFileSelector.tsx +2 -2
- package/src/constants/prompts.ts +1 -1
- package/src/projectOnboardingState.ts +3 -1
- package/src/services/SessionMemory/prompts.ts +2 -2
- package/src/services/settingsSync/types.ts +1 -1
- package/src/skills/bundled/remember.ts +9 -9
- package/src/tools/FileEditTool/FileEditTool.ts +1 -1
- package/src/tools/FileWriteTool/FileWriteTool.ts +2 -2
- package/src/utils/claudemd.ts +79 -29
- package/src/utils/config.ts +4 -4
- package/src/utils/theme.ts +28 -28
package/package.json
CHANGED
package/src/commands/init.ts
CHANGED
|
@@ -3,15 +3,15 @@ import type { Command } from '../commands.js'
|
|
|
3
3
|
import { maybeMarkProjectOnboardingComplete } from '../projectOnboardingState.js'
|
|
4
4
|
import { isEnvTruthy } from '../utils/envUtils.js'
|
|
5
5
|
|
|
6
|
-
const OLD_INIT_PROMPT = `Please analyze this codebase and create a
|
|
6
|
+
const OLD_INIT_PROMPT = `Please analyze this codebase and create a XELA.md file, which will be given to future instances of Xela to operate in this repository.
|
|
7
7
|
|
|
8
8
|
What to add:
|
|
9
9
|
1. Commands that will be commonly used, such as how to build, lint, and run tests. Include the necessary commands to develop in this codebase, such as how to run a single test.
|
|
10
10
|
2. High-level code architecture and structure so that future instances can be productive more quickly. Focus on the "big picture" architecture that requires reading multiple files to understand.
|
|
11
11
|
|
|
12
12
|
Usage notes:
|
|
13
|
-
- If there's already a
|
|
14
|
-
- When you make the initial
|
|
13
|
+
- If there's already a XELA.md, suggest improvements to it.
|
|
14
|
+
- When you make the initial XELA.md, do not repeat yourself and do not include obvious instructions like "Provide helpful error messages to users", "Write unit tests for all new utilities", "Never include sensitive information (API keys, tokens) in code or commits".
|
|
15
15
|
- Avoid listing every component or file structure that can be easily discovered.
|
|
16
16
|
- Don't include generic development practices.
|
|
17
17
|
- If there are Cursor rules (in .cursor/rules/ or .cursorrules) or Copilot rules (in .github/copilot-instructions.md), make sure to include the important parts.
|
|
@@ -20,30 +20,30 @@ Usage notes:
|
|
|
20
20
|
- Be sure to prefix the file with the following text:
|
|
21
21
|
|
|
22
22
|
\`\`\`
|
|
23
|
-
#
|
|
23
|
+
# XELA.md
|
|
24
24
|
|
|
25
|
-
This file provides guidance to
|
|
25
|
+
This file provides guidance to Xela (claude.ai/code) when working with code in this repository.
|
|
26
26
|
\`\`\``
|
|
27
27
|
|
|
28
|
-
const NEW_INIT_PROMPT = `Set up a minimal
|
|
28
|
+
const NEW_INIT_PROMPT = `Set up a minimal XELA.md (and optionally skills and hooks) for this repo. XELA.md is loaded into every Xela session, so it must be concise — only include what Claude would get wrong without it.
|
|
29
29
|
|
|
30
30
|
## Phase 1: Ask what to set up
|
|
31
31
|
|
|
32
32
|
Use AskUserQuestion to find out what the user wants:
|
|
33
33
|
|
|
34
|
-
- "Which
|
|
35
|
-
Options: "Project
|
|
34
|
+
- "Which XELA.md files should /init set up?"
|
|
35
|
+
Options: "Project XELA.md" | "Personal XELA.local.md" | "Both project + personal"
|
|
36
36
|
Description for project: "Team-shared instructions checked into source control — architecture, coding standards, common workflows."
|
|
37
37
|
Description for personal: "Your private preferences for this project (gitignored, not shared) — your role, sandbox URLs, preferred test data, workflow quirks."
|
|
38
38
|
|
|
39
39
|
- "Also set up skills and hooks?"
|
|
40
|
-
Options: "Skills + hooks" | "Skills only" | "Hooks only" | "Neither, just
|
|
40
|
+
Options: "Skills + hooks" | "Skills only" | "Hooks only" | "Neither, just XELA.md"
|
|
41
41
|
Description for skills: "On-demand capabilities you or Claude invoke with \`/skill-name\` — good for repeatable workflows and reference knowledge."
|
|
42
42
|
Description for hooks: "Deterministic shell commands that run on tool events (e.g., format after every edit). Claude can't skip them."
|
|
43
43
|
|
|
44
44
|
## Phase 2: Explore the codebase
|
|
45
45
|
|
|
46
|
-
Launch a subagent to survey the codebase, and ask it to read key files to understand the project: manifest files (package.json, Cargo.toml, pyproject.toml, go.mod, pom.xml, etc.), README, Makefile/build configs, CI config, existing
|
|
46
|
+
Launch a subagent to survey the codebase, and ask it to read key files to understand the project: manifest files (package.json, Cargo.toml, pyproject.toml, go.mod, pom.xml, etc.), README, Makefile/build configs, CI config, existing XELA.md, .claude/rules/, AGENTS.md, .cursor/rules or .cursorrules, .github/copilot-instructions.md, .windsurfrules, .clinerules, .mcp.json.
|
|
47
47
|
|
|
48
48
|
Detect:
|
|
49
49
|
- Build, test, and lint commands (especially non-standard ones)
|
|
@@ -53,30 +53,30 @@ Detect:
|
|
|
53
53
|
- Non-obvious gotchas, required env vars, or workflow quirks
|
|
54
54
|
- Existing .claude/skills/ and .claude/rules/ directories
|
|
55
55
|
- Formatter configuration (prettier, biome, ruff, black, gofmt, rustfmt, or a unified format script like \`npm run format\` / \`make fmt\`)
|
|
56
|
-
- Git worktree usage: run \`git worktree list\` to check if this repo has multiple worktrees (only relevant if the user wants a personal
|
|
56
|
+
- Git worktree usage: run \`git worktree list\` to check if this repo has multiple worktrees (only relevant if the user wants a personal XELA.local.md)
|
|
57
57
|
|
|
58
58
|
Note what you could NOT figure out from code alone — these become interview questions.
|
|
59
59
|
|
|
60
60
|
## Phase 3: Fill in the gaps
|
|
61
61
|
|
|
62
|
-
Use AskUserQuestion to gather what you still need to write good
|
|
62
|
+
Use AskUserQuestion to gather what you still need to write good XELA.md files and skills. Ask only things the code can't answer.
|
|
63
63
|
|
|
64
|
-
If the user chose project
|
|
64
|
+
If the user chose project XELA.md or both: ask about codebase practices — non-obvious commands, gotchas, branch/PR conventions, required env setup, testing quirks. Skip things already in README or obvious from manifest files. Do not mark any options as "recommended" — this is about how their team works, not best practices.
|
|
65
65
|
|
|
66
|
-
If the user chose personal
|
|
66
|
+
If the user chose personal XELA.local.md or both: ask about them, not the codebase. Do not mark any options as "recommended" — this is about their personal preferences, not best practices. Examples of questions:
|
|
67
67
|
- What's their role on the team? (e.g., "backend engineer", "data scientist", "new hire onboarding")
|
|
68
68
|
- How familiar are they with this codebase and its languages/frameworks? (so Claude can calibrate explanation depth)
|
|
69
69
|
- Do they have personal sandbox URLs, test accounts, API key paths, or local setup details Claude should know?
|
|
70
|
-
- Only if Phase 2 found multiple git worktrees: ask whether their worktrees are nested inside the main repo (e.g., \`.claude/worktrees/<name>/\`) or siblings/external (e.g., \`../myrepo-feature/\`). If nested, the upward file walk finds the main repo's
|
|
70
|
+
- Only if Phase 2 found multiple git worktrees: ask whether their worktrees are nested inside the main repo (e.g., \`.claude/worktrees/<name>/\`) or siblings/external (e.g., \`../myrepo-feature/\`). If nested, the upward file walk finds the main repo's XELA.local.md automatically — no special handling needed. If sibling/external, the personal content should live in a home-directory file (e.g., \`~/.claude/<project-name>-instructions.md\`) and each worktree gets a one-line XELA.local.md stub that imports it: \`@~/.claude/<project-name>-instructions.md\`. Never put this import in the project XELA.md — that would check a personal reference into the team-shared file.
|
|
71
71
|
- Any communication preferences? (e.g., "be terse", "always explain tradeoffs", "don't summarize at the end")
|
|
72
72
|
|
|
73
|
-
**Synthesize a proposal from Phase 2 findings** — e.g., format-on-edit if a formatter exists, a \`/verify\` skill if tests exist, a
|
|
73
|
+
**Synthesize a proposal from Phase 2 findings** — e.g., format-on-edit if a formatter exists, a \`/verify\` skill if tests exist, a XELA.md note for anything from the gap-fill answers that's a guideline rather than a workflow. For each, pick the artifact type that fits, **constrained by the Phase 1 skills+hooks choice**:
|
|
74
74
|
|
|
75
75
|
- **Hook** (stricter) — deterministic shell command on a tool event; Claude can't skip it. Fits mechanical, fast, per-edit steps: formatting, linting, running a quick test on the changed file.
|
|
76
76
|
- **Skill** (on-demand) — you or Claude invoke \`/skill-name\` when you want it. Fits workflows that don't belong on every edit: deep verification, session reports, deploys.
|
|
77
|
-
- **
|
|
77
|
+
- **XELA.md note** (looser) — influences Claude's behavior but not enforced. Fits communication/thinking preferences: "plan before coding", "be terse", "explain tradeoffs".
|
|
78
78
|
|
|
79
|
-
**Respect Phase 1's skills+hooks choice as a hard filter**: if the user picked "Skills only", downgrade any hook you'd suggest to a skill or a
|
|
79
|
+
**Respect Phase 1's skills+hooks choice as a hard filter**: if the user picked "Skills only", downgrade any hook you'd suggest to a skill or a XELA.md note. If "Hooks only", downgrade skills to hooks (where mechanically possible) or notes. If "Neither", everything becomes a XELA.md note. Never propose an artifact type the user didn't opt into.
|
|
80
80
|
|
|
81
81
|
**Show the proposal via AskUserQuestion's \`preview\` field, not as a separate text message** — the dialog overlays your output, so preceding text is hidden. The \`preview\` field renders markdown in a side-panel (like plan mode); the \`question\` field is plain-text-only. Structure it as:
|
|
82
82
|
|
|
@@ -86,17 +86,17 @@ If the user chose personal CLAUDE.local.md or both: ask about them, not the code
|
|
|
86
86
|
|
|
87
87
|
• **Format-on-edit hook** (automatic) — \`ruff format <file>\` via PostToolUse
|
|
88
88
|
• **/verify skill** (on-demand) — \`make lint && make typecheck && make test\`
|
|
89
|
-
• **
|
|
89
|
+
• **XELA.md note** (guideline) — "run lint/typecheck/test before marking done"
|
|
90
90
|
|
|
91
91
|
- Option labels stay short ("Looks good", "Drop the hook", "Drop the skill") — the tool auto-adds an "Other" free-text option, so don't add your own catch-all.
|
|
92
92
|
|
|
93
93
|
**Build the preference queue** from the accepted proposal. Each entry: {type: hook|skill|note, description, target file, any Phase-2-sourced details like the actual test/format command}. Phases 4-7 consume this queue.
|
|
94
94
|
|
|
95
|
-
## Phase 4: Write
|
|
95
|
+
## Phase 4: Write XELA.md (if user chose project or both)
|
|
96
96
|
|
|
97
|
-
Write a minimal
|
|
97
|
+
Write a minimal XELA.md at the project root. Every line must pass this test: "Would removing this cause Claude to make mistakes?" If no, cut it.
|
|
98
98
|
|
|
99
|
-
**Consume \`note\` entries from the Phase 3 preference queue whose target is
|
|
99
|
+
**Consume \`note\` entries from the Phase 3 preference queue whose target is XELA.md** (team-level notes) — add each as a concise line in the most relevant section. These are the behaviors the user wants Claude to follow but didn't need guaranteed (e.g., "propose a plan before implementing", "explain the tradeoffs when refactoring"). Leave personal-targeted notes for Phase 5.
|
|
100
100
|
|
|
101
101
|
Include:
|
|
102
102
|
- Build/test/lint commands Claude can't guess (non-standard scripts, flags, or sequences)
|
|
@@ -111,7 +111,7 @@ Exclude:
|
|
|
111
111
|
- File-by-file structure or component lists (Claude can discover these by reading the codebase)
|
|
112
112
|
- Standard language conventions Claude already knows
|
|
113
113
|
- Generic advice ("write clean code", "handle errors")
|
|
114
|
-
- Detailed API docs or long references — use \`@path/to/import\` syntax instead (e.g., \`@docs/api-reference.md\`) to inline content on demand without bloating
|
|
114
|
+
- Detailed API docs or long references — use \`@path/to/import\` syntax instead (e.g., \`@docs/api-reference.md\`) to inline content on demand without bloating XELA.md
|
|
115
115
|
- Information that changes frequently — reference the source with \`@path/to/import\` so Claude always reads the current version
|
|
116
116
|
- Long tutorials or walkthroughs (move to a separate file and reference with \`@path/to/import\`, or put in a skill)
|
|
117
117
|
- Commands obvious from manifest files (e.g., standard "npm test", "cargo test", "pytest")
|
|
@@ -123,22 +123,22 @@ Do not repeat yourself and do not make up sections like "Common Development Task
|
|
|
123
123
|
Prefix the file with:
|
|
124
124
|
|
|
125
125
|
\`\`\`
|
|
126
|
-
#
|
|
126
|
+
# XELA.md
|
|
127
127
|
|
|
128
|
-
This file provides guidance to
|
|
128
|
+
This file provides guidance to Xela (claude.ai/code) when working with code in this repository.
|
|
129
129
|
\`\`\`
|
|
130
130
|
|
|
131
|
-
If
|
|
131
|
+
If XELA.md already exists: read it, propose specific changes as diffs, and explain why each change improves it. Do not silently overwrite.
|
|
132
132
|
|
|
133
|
-
For projects with multiple concerns, suggest organizing instructions into \`.claude/rules/\` as separate focused files (e.g., \`code-style.md\`, \`testing.md\`, \`security.md\`). These are loaded automatically alongside
|
|
133
|
+
For projects with multiple concerns, suggest organizing instructions into \`.claude/rules/\` as separate focused files (e.g., \`code-style.md\`, \`testing.md\`, \`security.md\`). These are loaded automatically alongside XELA.md and can be scoped to specific file paths using \`paths\` frontmatter.
|
|
134
134
|
|
|
135
|
-
For projects with distinct subdirectories (monorepos, multi-module projects, etc.): mention that subdirectory
|
|
135
|
+
For projects with distinct subdirectories (monorepos, multi-module projects, etc.): mention that subdirectory XELA.md files can be added for module-specific instructions (they're loaded automatically when Claude works in those directories). Offer to create them if the user wants.
|
|
136
136
|
|
|
137
|
-
## Phase 5: Write
|
|
137
|
+
## Phase 5: Write XELA.local.md (if user chose personal or both)
|
|
138
138
|
|
|
139
|
-
Write a minimal
|
|
139
|
+
Write a minimal XELA.local.md at the project root. This file is automatically loaded alongside XELA.md. After creating it, add \`XELA.local.md\` to the project's .gitignore so it stays private.
|
|
140
140
|
|
|
141
|
-
**Consume \`note\` entries from the Phase 3 preference queue whose target is
|
|
141
|
+
**Consume \`note\` entries from the Phase 3 preference queue whose target is XELA.local.md** (personal-level notes) — add each as a concise line. If the user chose personal-only in Phase 1, this is the sole consumer of note entries.
|
|
142
142
|
|
|
143
143
|
Include:
|
|
144
144
|
- The user's role and familiarity with the codebase (so Claude can calibrate explanations)
|
|
@@ -147,9 +147,9 @@ Include:
|
|
|
147
147
|
|
|
148
148
|
Keep it short — only include what would make Claude's responses noticeably better for this user.
|
|
149
149
|
|
|
150
|
-
If Phase 2 found multiple git worktrees and the user confirmed they use sibling/external worktrees (not nested inside the main repo): the upward file walk won't find a single
|
|
150
|
+
If Phase 2 found multiple git worktrees and the user confirmed they use sibling/external worktrees (not nested inside the main repo): the upward file walk won't find a single XELA.local.md from all worktrees. Write the actual personal content to \`~/.claude/<project-name>-instructions.md\` and make XELA.local.md a one-line stub that imports it: \`@~/.claude/<project-name>-instructions.md\`. The user can copy this one-line stub to each sibling worktree. Never put this import in the project XELA.md. If worktrees are nested inside the main repo (e.g., \`.claude/worktrees/\`), no special handling is needed — the main repo's XELA.local.md is found automatically.
|
|
151
151
|
|
|
152
|
-
If
|
|
152
|
+
If XELA.local.md already exists: read it, propose specific additions, and do not silently overwrite.
|
|
153
153
|
|
|
154
154
|
## Phase 6: Suggest and create skills (if user chose "Skills + hooks" or "Skills only")
|
|
155
155
|
|
|
@@ -183,7 +183,7 @@ Both the user (\`/<skill-name>\`) and Claude can invoke skills by default. For w
|
|
|
183
183
|
|
|
184
184
|
## Phase 7: Suggest additional optimizations
|
|
185
185
|
|
|
186
|
-
Tell the user you're going to suggest a few additional optimizations now that
|
|
186
|
+
Tell the user you're going to suggest a few additional optimizations now that XELA.md and skills (if chosen) are in place.
|
|
187
187
|
|
|
188
188
|
Check the environment and ask about each gap you find (use AskUserQuestion):
|
|
189
189
|
|
|
@@ -195,7 +195,7 @@ Check the environment and ask about each gap you find (use AskUserQuestion):
|
|
|
195
195
|
|
|
196
196
|
For each hook preference (from the queue or the formatter fallback):
|
|
197
197
|
|
|
198
|
-
1. Target file: default based on the Phase 1
|
|
198
|
+
1. Target file: default based on the Phase 1 XELA.md choice — project → \`.claude/settings.json\` (team-shared, committed); personal → \`.claude/settings.local.json\`. Only ask if the user chose "both" in Phase 1 or the preference is ambiguous. Ask once for all hooks, not per-hook.
|
|
199
199
|
|
|
200
200
|
2. Pick the event and matcher from the preference:
|
|
201
201
|
- "after every edit" → \`PostToolUse\` with matcher \`Write|Edit\`
|
|
@@ -214,13 +214,13 @@ Act on each "yes" before moving on.
|
|
|
214
214
|
|
|
215
215
|
Recap what was set up — which files were written and the key points included in each. Remind the user these files are a starting point: they should review and tweak them, and can run \`/init\` again anytime to re-scan.
|
|
216
216
|
|
|
217
|
-
Then tell the user that you'll be introducing a few more suggestions for optimizing their codebase and
|
|
217
|
+
Then tell the user that you'll be introducing a few more suggestions for optimizing their codebase and Xela setup based on what you found. Present these as a single, well-formatted to-do list where every item is relevant to this repo. Put the most impactful items first.
|
|
218
218
|
|
|
219
219
|
When building the list, work through these checks and include only what applies:
|
|
220
220
|
- If frontend code was detected (React, Vue, Svelte, etc.): \`/plugin install frontend-design@claude-plugins-official\` gives Claude design principles and component patterns so it produces polished UI; \`/plugin install playwright@claude-plugins-official\` lets Claude launch a real browser, screenshot what it built, and fix visual bugs itself.
|
|
221
221
|
- If you found gaps in Phase 7 (missing GitHub CLI, missing linting) and the user said no: list them here with a one-line reason why each helps.
|
|
222
222
|
- If tests are missing or sparse: suggest setting up a test framework so Claude can verify its own changes.
|
|
223
|
-
- To help you create skills and optimize existing skills using evals,
|
|
223
|
+
- To help you create skills and optimize existing skills using evals, Xela has an official skill-creator plugin you can install. Install it with \`/plugin install skill-creator@claude-plugins-official\`, then run \`/skill-creator <skill-name>\` to create new skills or refine any existing skill. (Always include this one.)
|
|
224
224
|
- Browse official plugins with \`/plugin\` — these bundle skills, agents, hooks, and MCP servers that you may find helpful. You can also create your own custom plugins to share them with others. (Always include this one.)`
|
|
225
225
|
|
|
226
226
|
const command = {
|
|
@@ -230,8 +230,8 @@ const command = {
|
|
|
230
230
|
return feature('NEW_INIT') &&
|
|
231
231
|
(process.env.USER_TYPE === 'ant' ||
|
|
232
232
|
isEnvTruthy(process.env.CLAUDE_CODE_NEW_INIT))
|
|
233
|
-
? 'Initialize new
|
|
234
|
-
: 'Initialize a new
|
|
233
|
+
? 'Initialize new XELA.md file(s) and optional skills/hooks with codebase documentation'
|
|
234
|
+
: 'Initialize a new XELA.md file with codebase documentation'
|
|
235
235
|
},
|
|
236
236
|
contentLength: 0, // Dynamic content
|
|
237
237
|
progressMessage: 'analyzing your codebase',
|
|
@@ -31,44 +31,45 @@ type Segments = {
|
|
|
31
31
|
/** row 2 right (no bg): body curve + arm */
|
|
32
32
|
r2R: string;
|
|
33
33
|
};
|
|
34
|
+
// Xela "X" mascot — all poses show the same X logo
|
|
34
35
|
const POSES: Record<ClawdPose, Segments> = {
|
|
35
36
|
default: {
|
|
36
|
-
r1L: '
|
|
37
|
-
r1E: '
|
|
38
|
-
r1R: '
|
|
39
|
-
r2L: '
|
|
40
|
-
r2R: '
|
|
37
|
+
r1L: '╲ ',
|
|
38
|
+
r1E: ' ╳ ',
|
|
39
|
+
r1R: ' ╱',
|
|
40
|
+
r2L: '╱ ',
|
|
41
|
+
r2R: ' ╲'
|
|
41
42
|
},
|
|
42
43
|
'look-left': {
|
|
43
|
-
r1L: '
|
|
44
|
-
r1E: '
|
|
45
|
-
r1R: '
|
|
46
|
-
r2L: '
|
|
47
|
-
r2R: '
|
|
44
|
+
r1L: '╲ ',
|
|
45
|
+
r1E: ' ╳ ',
|
|
46
|
+
r1R: ' ╱',
|
|
47
|
+
r2L: '╱ ',
|
|
48
|
+
r2R: ' ╲'
|
|
48
49
|
},
|
|
49
50
|
'look-right': {
|
|
50
|
-
r1L: '
|
|
51
|
-
r1E: '
|
|
52
|
-
r1R: '
|
|
53
|
-
r2L: '
|
|
54
|
-
r2R: '
|
|
51
|
+
r1L: '╲ ',
|
|
52
|
+
r1E: ' ╳ ',
|
|
53
|
+
r1R: ' ╱',
|
|
54
|
+
r2L: '╱ ',
|
|
55
|
+
r2R: ' ╲'
|
|
55
56
|
},
|
|
56
57
|
'arms-up': {
|
|
57
|
-
r1L: '
|
|
58
|
-
r1E: '
|
|
59
|
-
r1R: '
|
|
60
|
-
r2L: '
|
|
61
|
-
r2R: '
|
|
58
|
+
r1L: '╲ ',
|
|
59
|
+
r1E: ' ╳ ',
|
|
60
|
+
r1R: ' ╱',
|
|
61
|
+
r2L: '╱ ',
|
|
62
|
+
r2R: ' ╲'
|
|
62
63
|
}
|
|
63
64
|
};
|
|
64
65
|
|
|
65
66
|
// Apple Terminal uses a bg-fill trick (see below), so only eye poses make
|
|
66
67
|
// sense. Arm poses fall back to default.
|
|
67
68
|
const APPLE_EYES: Record<ClawdPose, string> = {
|
|
68
|
-
default: '
|
|
69
|
-
'look-left': '
|
|
70
|
-
'look-right': '
|
|
71
|
-
'arms-up': '
|
|
69
|
+
default: ' ╲ ╳ ╱ ',
|
|
70
|
+
'look-left': ' ╲ ╳ ╱ ',
|
|
71
|
+
'look-right': ' ╲ ╳ ╱ ',
|
|
72
|
+
'arms-up': ' ╲ ╳ ╱ '
|
|
72
73
|
};
|
|
73
74
|
export function Clawd(t0) {
|
|
74
75
|
const $ = _c(26);
|
|
@@ -140,7 +141,7 @@ export function Clawd(t0) {
|
|
|
140
141
|
}
|
|
141
142
|
let t8;
|
|
142
143
|
if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
|
|
143
|
-
t8 = <Text color="clawd_body"
|
|
144
|
+
t8 = <Text color="clawd_body"> ╳ </Text>;
|
|
144
145
|
$[16] = t8;
|
|
145
146
|
} else {
|
|
146
147
|
t8 = $[16];
|
|
@@ -164,7 +165,7 @@ export function Clawd(t0) {
|
|
|
164
165
|
}
|
|
165
166
|
let t11;
|
|
166
167
|
if ($[22] === Symbol.for("react.memo_cache_sentinel")) {
|
|
167
|
-
t11 = <Text color="clawd_body">{" "}
|
|
168
|
+
t11 = <Text color="clawd_body">{" "}XELA{" "}</Text>;
|
|
168
169
|
$[22] = t11;
|
|
169
170
|
} else {
|
|
170
171
|
t11 = $[22];
|
|
@@ -975,7 +975,7 @@ export function Config({
|
|
|
975
975
|
}
|
|
976
976
|
}] : []), ...(shouldShowExternalIncludesToggle ? [{
|
|
977
977
|
id: 'showExternalIncludesDialog',
|
|
978
|
-
label: 'External
|
|
978
|
+
label: 'External XELA.md includes',
|
|
979
979
|
value: (() => {
|
|
980
980
|
const projectConfig = getCurrentProjectConfig();
|
|
981
981
|
if (projectConfig.hasClaudeMdExternalIncludesApproved) {
|
|
@@ -48,8 +48,8 @@ export function MemoryFileSelector(t0) {
|
|
|
48
48
|
onCancel
|
|
49
49
|
} = t0;
|
|
50
50
|
const existingMemoryFiles = use(getMemoryFiles());
|
|
51
|
-
const userMemoryPath = join(getClaudeConfigHomeDir(), "
|
|
52
|
-
const projectMemoryPath = join(getOriginalCwd(), "
|
|
51
|
+
const userMemoryPath = join(getClaudeConfigHomeDir(), "XELA.md");
|
|
52
|
+
const projectMemoryPath = join(getOriginalCwd(), "XELA.md");
|
|
53
53
|
const hasUserMemory = existingMemoryFiles.some(f => f.path === userMemoryPath);
|
|
54
54
|
const hasProjectMemory = existingMemoryFiles.some(f_0 => f_0.path === projectMemoryPath);
|
|
55
55
|
const allMemoryFiles = [...existingMemoryFiles.filter(_temp).map(_temp2), ...(hasUserMemory ? [] : [{
|
package/src/constants/prompts.ts
CHANGED
|
@@ -255,7 +255,7 @@ function getSimpleDoingTasksSection(): string {
|
|
|
255
255
|
function getActionsSection(): string {
|
|
256
256
|
return `# Executing actions with care
|
|
257
257
|
|
|
258
|
-
Carefully consider the reversibility and blast radius of actions. Generally you can freely take local, reversible actions like editing files or running tests. But for actions that are hard to reverse, affect shared systems beyond your local environment, or could otherwise be risky or destructive, check with the user before proceeding. The cost of pausing to confirm is low, while the cost of an unwanted action (lost work, unintended messages sent, deleted branches) can be very high. For actions like these, consider the context, the action, and user instructions, and by default transparently communicate the action and ask for confirmation before proceeding. This default can be changed by user instructions - if explicitly asked to operate more autonomously, then you may proceed without confirmation, but still attend to the risks and consequences when taking actions. A user approving an action (like a git push) once does NOT mean that they approve it in all contexts, so unless actions are authorized in advance in durable instructions like
|
|
258
|
+
Carefully consider the reversibility and blast radius of actions. Generally you can freely take local, reversible actions like editing files or running tests. But for actions that are hard to reverse, affect shared systems beyond your local environment, or could otherwise be risky or destructive, check with the user before proceeding. The cost of pausing to confirm is low, while the cost of an unwanted action (lost work, unintended messages sent, deleted branches) can be very high. For actions like these, consider the context, the action, and user instructions, and by default transparently communicate the action and ask for confirmation before proceeding. This default can be changed by user instructions - if explicitly asked to operate more autonomously, then you may proceed without confirmation, but still attend to the risks and consequences when taking actions. A user approving an action (like a git push) once does NOT mean that they approve it in all contexts, so unless actions are authorized in advance in durable instructions like XELA.md files, always confirm first. Authorization stands for the scope specified, not beyond. Match the scope of your actions to what was actually requested.
|
|
259
259
|
|
|
260
260
|
Examples of the kind of risky actions that warrant user confirmation:
|
|
261
261
|
- Destructive operations: deleting files/branches, dropping database tables, killing processes, rm -rf, overwriting uncommitted changes
|
|
@@ -18,6 +18,8 @@ export type Step = {
|
|
|
18
18
|
|
|
19
19
|
export function getSteps(): Step[] {
|
|
20
20
|
const hasClaudeMd = getFsImplementation().existsSync(
|
|
21
|
+
join(getCwd(), 'XELA.md'),
|
|
22
|
+
) || getFsImplementation().existsSync(
|
|
21
23
|
join(getCwd(), 'CLAUDE.md'),
|
|
22
24
|
)
|
|
23
25
|
const isWorkspaceDirEmpty = isDirEmpty(getCwd())
|
|
@@ -32,7 +34,7 @@ export function getSteps(): Step[] {
|
|
|
32
34
|
},
|
|
33
35
|
{
|
|
34
36
|
key: 'claudemd',
|
|
35
|
-
text: 'Run /init to create a
|
|
37
|
+
text: 'Run /init to create a XELA.md file with project instructions',
|
|
36
38
|
isComplete: hasClaudeMd,
|
|
37
39
|
isCompletable: true,
|
|
38
40
|
isEnabled: !isWorkspaceDirEmpty,
|
|
@@ -43,7 +43,7 @@ _Step by step, what was attempted, done? Very terse summary for each step_
|
|
|
43
43
|
function getDefaultUpdatePrompt(): string {
|
|
44
44
|
return `IMPORTANT: This message and these instructions are NOT part of the actual user conversation. Do NOT include any references to "note-taking", "session notes extraction", or these update instructions in the notes content.
|
|
45
45
|
|
|
46
|
-
Based on the user conversation above (EXCLUDING this note-taking instruction message as well as system prompt,
|
|
46
|
+
Based on the user conversation above (EXCLUDING this note-taking instruction message as well as system prompt, xela.md entries, or any past session summaries), update the session notes file.
|
|
47
47
|
|
|
48
48
|
The file {{notesPath}} has already been read for you. Here are its current contents:
|
|
49
49
|
<current_notes_content>
|
|
@@ -63,7 +63,7 @@ CRITICAL RULES FOR EDITING:
|
|
|
63
63
|
- It's OK to skip updating a section if there are no substantial new insights to add. Do not add filler content like "No info yet", just leave sections blank/unedited if appropriate.
|
|
64
64
|
- Write DETAILED, INFO-DENSE content for each section - include specifics like file paths, function names, error messages, exact commands, technical details, etc.
|
|
65
65
|
- For "Key results", include the complete, exact output the user requested (e.g., full table, full answer, etc.)
|
|
66
|
-
- Do not include information that's already in the
|
|
66
|
+
- Do not include information that's already in the XELA.md files included in the context
|
|
67
67
|
- Keep each section under ~${MAX_SECTION_LENGTH} tokens/words - if a section is approaching this limit, condense it by cycling out less important details while preserving the most critical information
|
|
68
68
|
- Focus on actionable, specific information that would help someone understand or recreate the work discussed in the conversation
|
|
69
69
|
- IMPORTANT: Always update "Current State" to reflect the most recent work - this is critical for continuity after compaction
|
|
@@ -60,7 +60,7 @@ export type SettingsSyncUploadResult = {
|
|
|
60
60
|
*/
|
|
61
61
|
export const SYNC_KEYS = {
|
|
62
62
|
USER_SETTINGS: '~/.claude/settings.json',
|
|
63
|
-
USER_MEMORY: '~/.claude/
|
|
63
|
+
USER_MEMORY: '~/.claude/XELA.md',
|
|
64
64
|
projectSettings: (projectId: string) =>
|
|
65
65
|
`projects/${projectId}/.claude/settings.local.json`,
|
|
66
66
|
projectMemory: (projectId: string) => `projects/${projectId}/CLAUDE.local.md`,
|
|
@@ -14,7 +14,7 @@ Review the user's memory landscape and produce a clear report of proposed change
|
|
|
14
14
|
## Steps
|
|
15
15
|
|
|
16
16
|
### 1. Gather all memory layers
|
|
17
|
-
Read
|
|
17
|
+
Read XELA.md and XELA.local.md from the project root (if they exist). Your auto-memory content is already in your system prompt — review it there. Note which team memory sections exist, if any.
|
|
18
18
|
|
|
19
19
|
**Success criteria**: You have the contents of all memory layers and can compare them.
|
|
20
20
|
|
|
@@ -23,13 +23,13 @@ For each substantive entry in auto-memory, determine the best destination:
|
|
|
23
23
|
|
|
24
24
|
| Destination | What belongs there | Examples |
|
|
25
25
|
|---|---|---|
|
|
26
|
-
| **
|
|
27
|
-
| **
|
|
26
|
+
| **XELA.md** | Project conventions and instructions for Claude that all contributors should follow | "use bun not npm", "API routes use kebab-case", "test command is bun test", "prefer functional style" |
|
|
27
|
+
| **XELA.local.md** | Personal instructions for Claude specific to this user, not applicable to other contributors | "I prefer concise responses", "always explain trade-offs", "don't auto-commit", "run tests before committing" |
|
|
28
28
|
| **Team memory** | Org-wide knowledge that applies across repositories (only if team memory is configured) | "deploy PRs go through #deploy-queue", "staging is at staging.internal", "platform team owns infra" |
|
|
29
29
|
| **Stay in auto-memory** | Working notes, temporary context, or entries that don't clearly fit elsewhere | Session-specific observations, uncertain patterns |
|
|
30
30
|
|
|
31
31
|
**Important distinctions:**
|
|
32
|
-
-
|
|
32
|
+
- XELA.md and XELA.local.md contain instructions for Claude, not user preferences for external tools (editor theme, IDE keybindings, etc. don't belong in either)
|
|
33
33
|
- Workflow practices (PR conventions, merge strategies, branch naming) are ambiguous — ask the user whether they're personal or team-wide
|
|
34
34
|
- When unsure, ask rather than guess
|
|
35
35
|
|
|
@@ -37,8 +37,8 @@ For each substantive entry in auto-memory, determine the best destination:
|
|
|
37
37
|
|
|
38
38
|
### 3. Identify cleanup opportunities
|
|
39
39
|
Scan across all layers for:
|
|
40
|
-
- **Duplicates**: Auto-memory entries already captured in
|
|
41
|
-
- **Outdated**:
|
|
40
|
+
- **Duplicates**: Auto-memory entries already captured in XELA.md or XELA.local.md → propose removing from auto-memory
|
|
41
|
+
- **Outdated**: XELA.md or XELA.local.md entries contradicted by newer auto-memory entries → propose updating the older layer
|
|
42
42
|
- **Conflicts**: Contradictions between any two layers → propose resolution, noting which is more recent
|
|
43
43
|
|
|
44
44
|
**Success criteria**: All cross-layer issues identified.
|
|
@@ -50,7 +50,7 @@ Output a structured report grouped by action type:
|
|
|
50
50
|
3. **Ambiguous** — entries where you need the user's input on destination
|
|
51
51
|
4. **No action needed** — brief note on entries that should stay put
|
|
52
52
|
|
|
53
|
-
If auto-memory is empty, say so and offer to review
|
|
53
|
+
If auto-memory is empty, say so and offer to review XELA.md for cleanup.
|
|
54
54
|
|
|
55
55
|
**Success criteria**: User can review and approve/reject each proposal individually.
|
|
56
56
|
|
|
@@ -64,9 +64,9 @@ If auto-memory is empty, say so and offer to review CLAUDE.md for cleanup.
|
|
|
64
64
|
registerBundledSkill({
|
|
65
65
|
name: 'remember',
|
|
66
66
|
description:
|
|
67
|
-
'Review auto-memory entries and propose promotions to
|
|
67
|
+
'Review auto-memory entries and propose promotions to XELA.md, XELA.local.md, or shared memory. Also detects outdated, conflicting, and duplicate entries across memory layers.',
|
|
68
68
|
whenToUse:
|
|
69
|
-
'Use when the user wants to review, organize, or promote their auto-memory entries. Also useful for cleaning up outdated or conflicting entries across
|
|
69
|
+
'Use when the user wants to review, organize, or promote their auto-memory entries. Also useful for cleaning up outdated or conflicting entries across XELA.md, XELA.local.md, and auto-memory.',
|
|
70
70
|
userInvocable: true,
|
|
71
71
|
isEnabled: () => isAutoMemoryEnabled(),
|
|
72
72
|
async getPromptForCommand(args) {
|
|
@@ -525,7 +525,7 @@ export const FileEditTool = buildTool({
|
|
|
525
525
|
})
|
|
526
526
|
|
|
527
527
|
// 7. Log events
|
|
528
|
-
if (absoluteFilePath.endsWith(`${sep}CLAUDE.md`)) {
|
|
528
|
+
if (absoluteFilePath.endsWith(`${sep}XELA.md`) || absoluteFilePath.endsWith(`${sep}CLAUDE.md`)) {
|
|
529
529
|
logEvent('tengu_write_claudemd', {})
|
|
530
530
|
}
|
|
531
531
|
countLinesChanged(patch)
|
|
@@ -336,8 +336,8 @@ export const FileWriteTool = buildTool({
|
|
|
336
336
|
limit: undefined,
|
|
337
337
|
})
|
|
338
338
|
|
|
339
|
-
// Log when writing to CLAUDE.md
|
|
340
|
-
if (fullFilePath.endsWith(`${sep}CLAUDE.md`)) {
|
|
339
|
+
// Log when writing to XELA.md or CLAUDE.md
|
|
340
|
+
if (fullFilePath.endsWith(`${sep}XELA.md`) || fullFilePath.endsWith(`${sep}CLAUDE.md`)) {
|
|
341
341
|
logEvent('tengu_write_claudemd', {})
|
|
342
342
|
}
|
|
343
343
|
|
package/src/utils/claudemd.ts
CHANGED
|
@@ -883,20 +883,39 @@ export const getMemoryFiles = memoize(
|
|
|
883
883
|
pathInWorkingPath(dir, canonicalRoot) &&
|
|
884
884
|
!pathInWorkingPath(dir, gitRoot)
|
|
885
885
|
|
|
886
|
-
// Try reading CLAUDE.md (Project) - only if projectSettings is enabled
|
|
886
|
+
// Try reading XELA.md or CLAUDE.md (Project) - only if projectSettings is enabled
|
|
887
887
|
if (isSettingSourceEnabled('projectSettings') && !skipProject) {
|
|
888
|
-
|
|
888
|
+
// Prefer XELA.md, fall back to CLAUDE.md for backwards compatibility
|
|
889
|
+
const xelaPath = join(dir, 'XELA.md')
|
|
890
|
+
const claudePath = join(dir, 'CLAUDE.md')
|
|
889
891
|
result.push(
|
|
890
892
|
...(await processMemoryFile(
|
|
891
|
-
|
|
893
|
+
xelaPath,
|
|
894
|
+
'Project',
|
|
895
|
+
processedPaths,
|
|
896
|
+
includeExternal,
|
|
897
|
+
)),
|
|
898
|
+
)
|
|
899
|
+
result.push(
|
|
900
|
+
...(await processMemoryFile(
|
|
901
|
+
claudePath,
|
|
892
902
|
'Project',
|
|
893
903
|
processedPaths,
|
|
894
904
|
includeExternal,
|
|
895
905
|
)),
|
|
896
906
|
)
|
|
897
907
|
|
|
898
|
-
// Try reading .claude/CLAUDE.md (Project)
|
|
908
|
+
// Try reading .claude/XELA.md or .claude/CLAUDE.md (Project)
|
|
909
|
+
const dotXelaPath = join(dir, '.claude', 'XELA.md')
|
|
899
910
|
const dotClaudePath = join(dir, '.claude', 'CLAUDE.md')
|
|
911
|
+
result.push(
|
|
912
|
+
...(await processMemoryFile(
|
|
913
|
+
dotXelaPath,
|
|
914
|
+
'Project',
|
|
915
|
+
processedPaths,
|
|
916
|
+
includeExternal,
|
|
917
|
+
)),
|
|
918
|
+
)
|
|
900
919
|
result.push(
|
|
901
920
|
...(await processMemoryFile(
|
|
902
921
|
dotClaudePath,
|
|
@@ -919,8 +938,17 @@ export const getMemoryFiles = memoize(
|
|
|
919
938
|
)
|
|
920
939
|
}
|
|
921
940
|
|
|
922
|
-
// Try reading CLAUDE.local.md (Local) - only if localSettings is enabled
|
|
941
|
+
// Try reading XELA.local.md or CLAUDE.local.md (Local) - only if localSettings is enabled
|
|
923
942
|
if (isSettingSourceEnabled('localSettings')) {
|
|
943
|
+
const xelaLocalPath = join(dir, 'XELA.local.md')
|
|
944
|
+
result.push(
|
|
945
|
+
...(await processMemoryFile(
|
|
946
|
+
xelaLocalPath,
|
|
947
|
+
'Local',
|
|
948
|
+
processedPaths,
|
|
949
|
+
includeExternal,
|
|
950
|
+
)),
|
|
951
|
+
)
|
|
924
952
|
const localPath = join(dir, 'CLAUDE.local.md')
|
|
925
953
|
result.push(
|
|
926
954
|
...(await processMemoryFile(
|
|
@@ -940,7 +968,16 @@ export const getMemoryFiles = memoize(
|
|
|
940
968
|
if (isEnvTruthy(process.env.CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD)) {
|
|
941
969
|
const additionalDirs = getAdditionalDirectoriesForClaudeMd()
|
|
942
970
|
for (const dir of additionalDirs) {
|
|
943
|
-
// Try reading CLAUDE.md from the additional directory
|
|
971
|
+
// Try reading XELA.md or CLAUDE.md from the additional directory
|
|
972
|
+
const xelaPath_add = join(dir, 'XELA.md')
|
|
973
|
+
result.push(
|
|
974
|
+
...(await processMemoryFile(
|
|
975
|
+
xelaPath_add,
|
|
976
|
+
'Project',
|
|
977
|
+
processedPaths,
|
|
978
|
+
includeExternal,
|
|
979
|
+
)),
|
|
980
|
+
)
|
|
944
981
|
const projectPath = join(dir, 'CLAUDE.md')
|
|
945
982
|
result.push(
|
|
946
983
|
...(await processMemoryFile(
|
|
@@ -951,7 +988,16 @@ export const getMemoryFiles = memoize(
|
|
|
951
988
|
)),
|
|
952
989
|
)
|
|
953
990
|
|
|
954
|
-
// Try reading .claude/CLAUDE.md from the additional directory
|
|
991
|
+
// Try reading .claude/XELA.md or .claude/CLAUDE.md from the additional directory
|
|
992
|
+
const dotXelaPath_add = join(dir, '.claude', 'XELA.md')
|
|
993
|
+
result.push(
|
|
994
|
+
...(await processMemoryFile(
|
|
995
|
+
dotXelaPath_add,
|
|
996
|
+
'Project',
|
|
997
|
+
processedPaths,
|
|
998
|
+
includeExternal,
|
|
999
|
+
)),
|
|
1000
|
+
)
|
|
955
1001
|
const dotClaudePath = join(dir, '.claude', 'CLAUDE.md')
|
|
956
1002
|
result.push(
|
|
957
1003
|
...(await processMemoryFile(
|
|
@@ -1253,30 +1299,34 @@ export async function getMemoryFilesForNestedDirectory(
|
|
|
1253
1299
|
): Promise<MemoryFileInfo[]> {
|
|
1254
1300
|
const result: MemoryFileInfo[] = []
|
|
1255
1301
|
|
|
1256
|
-
// Process project memory files (CLAUDE.md and .claude/CLAUDE.md)
|
|
1302
|
+
// Process project memory files (XELA.md/CLAUDE.md and .claude/XELA.md/.claude/CLAUDE.md)
|
|
1257
1303
|
if (isSettingSourceEnabled('projectSettings')) {
|
|
1258
|
-
const
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
)
|
|
1275
|
-
|
|
1304
|
+
for (const fname of ['XELA.md', 'CLAUDE.md']) {
|
|
1305
|
+
result.push(
|
|
1306
|
+
...(await processMemoryFile(
|
|
1307
|
+
join(dir, fname),
|
|
1308
|
+
'Project',
|
|
1309
|
+
processedPaths,
|
|
1310
|
+
false,
|
|
1311
|
+
)),
|
|
1312
|
+
)
|
|
1313
|
+
result.push(
|
|
1314
|
+
...(await processMemoryFile(
|
|
1315
|
+
join(dir, '.claude', fname),
|
|
1316
|
+
'Project',
|
|
1317
|
+
processedPaths,
|
|
1318
|
+
false,
|
|
1319
|
+
)),
|
|
1320
|
+
)
|
|
1321
|
+
}
|
|
1276
1322
|
}
|
|
1277
1323
|
|
|
1278
|
-
// Process local memory file (CLAUDE.local.md)
|
|
1324
|
+
// Process local memory file (XELA.local.md/CLAUDE.local.md)
|
|
1279
1325
|
if (isSettingSourceEnabled('localSettings')) {
|
|
1326
|
+
const xelaLocalPath = join(dir, 'XELA.local.md')
|
|
1327
|
+
result.push(
|
|
1328
|
+
...(await processMemoryFile(xelaLocalPath, 'Local', processedPaths, false)),
|
|
1329
|
+
)
|
|
1280
1330
|
const localPath = join(dir, 'CLAUDE.local.md')
|
|
1281
1331
|
result.push(
|
|
1282
1332
|
...(await processMemoryFile(localPath, 'Local', processedPaths, false)),
|
|
@@ -1435,8 +1485,8 @@ export async function shouldShowClaudeMdExternalIncludesWarning(): Promise<boole
|
|
|
1435
1485
|
export function isMemoryFilePath(filePath: string): boolean {
|
|
1436
1486
|
const name = basename(filePath)
|
|
1437
1487
|
|
|
1438
|
-
// CLAUDE.md or CLAUDE.local.md anywhere
|
|
1439
|
-
if (name === 'CLAUDE.md' || name === 'CLAUDE.local.md') {
|
|
1488
|
+
// XELA.md, CLAUDE.md, XELA.local.md, or CLAUDE.local.md anywhere
|
|
1489
|
+
if (name === 'XELA.md' || name === 'CLAUDE.md' || name === 'XELA.local.md' || name === 'CLAUDE.local.md') {
|
|
1440
1490
|
return true
|
|
1441
1491
|
}
|
|
1442
1492
|
|
package/src/utils/config.ts
CHANGED
|
@@ -1781,13 +1781,13 @@ export function getMemoryPath(memoryType: MemoryType): string {
|
|
|
1781
1781
|
|
|
1782
1782
|
switch (memoryType) {
|
|
1783
1783
|
case 'User':
|
|
1784
|
-
return join(getClaudeConfigHomeDir(), '
|
|
1784
|
+
return join(getClaudeConfigHomeDir(), 'XELA.md')
|
|
1785
1785
|
case 'Local':
|
|
1786
|
-
return join(cwd, '
|
|
1786
|
+
return join(cwd, 'XELA.local.md')
|
|
1787
1787
|
case 'Project':
|
|
1788
|
-
return join(cwd, '
|
|
1788
|
+
return join(cwd, 'XELA.md')
|
|
1789
1789
|
case 'Managed':
|
|
1790
|
-
return join(getManagedFilePath(), '
|
|
1790
|
+
return join(getManagedFilePath(), 'XELA.md')
|
|
1791
1791
|
case 'AutoMem':
|
|
1792
1792
|
return getAutoMemEntrypoint()
|
|
1793
1793
|
}
|
package/src/utils/theme.ts
CHANGED
|
@@ -115,10 +115,10 @@ export type ThemeSetting = (typeof THEME_SETTINGS)[number]
|
|
|
115
115
|
const lightTheme: Theme = {
|
|
116
116
|
autoAccept: 'rgb(135,0,255)', // Electric violet
|
|
117
117
|
bashBorder: 'rgb(255,0,135)', // Vibrant pink
|
|
118
|
-
claude: 'rgb(
|
|
119
|
-
claudeShimmer: 'rgb(
|
|
120
|
-
claudeBlue_FOR_SYSTEM_SPINNER: 'rgb(
|
|
121
|
-
claudeBlueShimmer_FOR_SYSTEM_SPINNER: 'rgb(
|
|
118
|
+
claude: 'rgb(0,200,180)', // Xela teal
|
|
119
|
+
claudeShimmer: 'rgb(50,230,210)', // Lighter teal for shimmer effect
|
|
120
|
+
claudeBlue_FOR_SYSTEM_SPINNER: 'rgb(0,180,200)', // Cyan-teal for system spinner
|
|
121
|
+
claudeBlueShimmer_FOR_SYSTEM_SPINNER: 'rgb(50,210,230)', // Lighter cyan-teal for spinner shimmer
|
|
122
122
|
permission: 'rgb(87,105,247)', // Medium blue
|
|
123
123
|
permissionShimmer: 'rgb(137,155,255)', // Lighter blue for shimmer effect
|
|
124
124
|
planMode: 'rgb(0,102,102)', // Muted teal
|
|
@@ -158,7 +158,7 @@ const lightTheme: Theme = {
|
|
|
158
158
|
// Chrome colors
|
|
159
159
|
chromeYellow: 'rgb(251,188,4)', // Chrome yellow
|
|
160
160
|
// TUI V2 colors
|
|
161
|
-
clawd_body: 'rgb(
|
|
161
|
+
clawd_body: 'rgb(0,200,180)',
|
|
162
162
|
clawd_background: 'rgb(0,0,0)',
|
|
163
163
|
userMessageBackground: 'rgb(240, 240, 240)', // Slightly darker grey for optimal contrast
|
|
164
164
|
userMessageBackgroundHover: 'rgb(252, 252, 252)', // ≥250 to quantize distinct from base at 256-color level
|
|
@@ -173,7 +173,7 @@ const lightTheme: Theme = {
|
|
|
173
173
|
fastModeShimmer: 'rgb(255,150,50)', // Lighter orange for shimmer
|
|
174
174
|
// Brief/assistant mode
|
|
175
175
|
briefLabelYou: 'rgb(37,99,235)', // Blue
|
|
176
|
-
briefLabelClaude: 'rgb(
|
|
176
|
+
briefLabelClaude: 'rgb(0,200,180)', // Xela teal
|
|
177
177
|
rainbow_red: 'rgb(235,95,87)',
|
|
178
178
|
rainbow_orange: 'rgb(245,139,87)',
|
|
179
179
|
rainbow_yellow: 'rgb(250,195,95)',
|
|
@@ -197,8 +197,8 @@ const lightTheme: Theme = {
|
|
|
197
197
|
const lightAnsiTheme: Theme = {
|
|
198
198
|
autoAccept: 'ansi:magenta',
|
|
199
199
|
bashBorder: 'ansi:magenta',
|
|
200
|
-
claude: 'ansi:
|
|
201
|
-
claudeShimmer: 'ansi:
|
|
200
|
+
claude: 'ansi:cyanBright',
|
|
201
|
+
claudeShimmer: 'ansi:cyan',
|
|
202
202
|
claudeBlue_FOR_SYSTEM_SPINNER: 'ansi:blue',
|
|
203
203
|
claudeBlueShimmer_FOR_SYSTEM_SPINNER: 'ansi:blueBright',
|
|
204
204
|
permission: 'ansi:blue',
|
|
@@ -240,7 +240,7 @@ const lightAnsiTheme: Theme = {
|
|
|
240
240
|
// Chrome colors
|
|
241
241
|
chromeYellow: 'ansi:yellow', // Chrome yellow
|
|
242
242
|
// TUI V2 colors
|
|
243
|
-
clawd_body: 'ansi:
|
|
243
|
+
clawd_body: 'ansi:cyanBright',
|
|
244
244
|
clawd_background: 'ansi:black',
|
|
245
245
|
userMessageBackground: 'ansi:white',
|
|
246
246
|
userMessageBackgroundHover: 'ansi:whiteBright',
|
|
@@ -254,7 +254,7 @@ const lightAnsiTheme: Theme = {
|
|
|
254
254
|
fastMode: 'ansi:red',
|
|
255
255
|
fastModeShimmer: 'ansi:redBright',
|
|
256
256
|
briefLabelYou: 'ansi:blue',
|
|
257
|
-
briefLabelClaude: 'ansi:
|
|
257
|
+
briefLabelClaude: 'ansi:cyanBright',
|
|
258
258
|
rainbow_red: 'ansi:red',
|
|
259
259
|
rainbow_orange: 'ansi:redBright',
|
|
260
260
|
rainbow_yellow: 'ansi:yellow',
|
|
@@ -278,8 +278,8 @@ const lightAnsiTheme: Theme = {
|
|
|
278
278
|
const darkAnsiTheme: Theme = {
|
|
279
279
|
autoAccept: 'ansi:magentaBright',
|
|
280
280
|
bashBorder: 'ansi:magentaBright',
|
|
281
|
-
claude: 'ansi:
|
|
282
|
-
claudeShimmer: 'ansi:
|
|
281
|
+
claude: 'ansi:cyanBright',
|
|
282
|
+
claudeShimmer: 'ansi:cyan',
|
|
283
283
|
claudeBlue_FOR_SYSTEM_SPINNER: 'ansi:blueBright',
|
|
284
284
|
claudeBlueShimmer_FOR_SYSTEM_SPINNER: 'ansi:blueBright',
|
|
285
285
|
permission: 'ansi:blueBright',
|
|
@@ -321,7 +321,7 @@ const darkAnsiTheme: Theme = {
|
|
|
321
321
|
// Chrome colors
|
|
322
322
|
chromeYellow: 'ansi:yellowBright', // Chrome yellow
|
|
323
323
|
// TUI V2 colors
|
|
324
|
-
clawd_body: 'ansi:
|
|
324
|
+
clawd_body: 'ansi:cyanBright',
|
|
325
325
|
clawd_background: 'ansi:black',
|
|
326
326
|
userMessageBackground: 'ansi:blackBright',
|
|
327
327
|
userMessageBackgroundHover: 'ansi:white',
|
|
@@ -335,7 +335,7 @@ const darkAnsiTheme: Theme = {
|
|
|
335
335
|
fastMode: 'ansi:redBright',
|
|
336
336
|
fastModeShimmer: 'ansi:redBright',
|
|
337
337
|
briefLabelYou: 'ansi:blueBright',
|
|
338
|
-
briefLabelClaude: 'ansi:
|
|
338
|
+
briefLabelClaude: 'ansi:cyanBright',
|
|
339
339
|
rainbow_red: 'ansi:red',
|
|
340
340
|
rainbow_orange: 'ansi:redBright',
|
|
341
341
|
rainbow_yellow: 'ansi:yellow',
|
|
@@ -359,8 +359,8 @@ const darkAnsiTheme: Theme = {
|
|
|
359
359
|
const lightDaltonizedTheme: Theme = {
|
|
360
360
|
autoAccept: 'rgb(135,0,255)', // Electric violet
|
|
361
361
|
bashBorder: 'rgb(0,102,204)', // Blue instead of pink
|
|
362
|
-
claude: 'rgb(
|
|
363
|
-
claudeShimmer: 'rgb(
|
|
362
|
+
claude: 'rgb(0,200,180)', // Xela teal
|
|
363
|
+
claudeShimmer: 'rgb(50,230,210)', // Lighter teal for shimmer effect
|
|
364
364
|
claudeBlue_FOR_SYSTEM_SPINNER: 'rgb(51,102,255)', // Bright blue for system spinner
|
|
365
365
|
claudeBlueShimmer_FOR_SYSTEM_SPINNER: 'rgb(101,152,255)', // Lighter bright blue for system spinner shimmer
|
|
366
366
|
permission: 'rgb(51,102,255)', // Bright blue
|
|
@@ -402,7 +402,7 @@ const lightDaltonizedTheme: Theme = {
|
|
|
402
402
|
// Chrome colors
|
|
403
403
|
chromeYellow: 'rgb(251,188,4)', // Chrome yellow
|
|
404
404
|
// TUI V2 colors
|
|
405
|
-
clawd_body: 'rgb(
|
|
405
|
+
clawd_body: 'rgb(0,200,180)',
|
|
406
406
|
clawd_background: 'rgb(0,0,0)',
|
|
407
407
|
userMessageBackground: 'rgb(220, 220, 220)', // Slightly darker grey for optimal contrast
|
|
408
408
|
userMessageBackgroundHover: 'rgb(232, 232, 232)', // ≥230 to quantize distinct from base at 256-color level
|
|
@@ -416,7 +416,7 @@ const lightDaltonizedTheme: Theme = {
|
|
|
416
416
|
fastMode: 'rgb(255,106,0)', // Electric orange (color-blind safe)
|
|
417
417
|
fastModeShimmer: 'rgb(255,150,50)', // Lighter orange for shimmer
|
|
418
418
|
briefLabelYou: 'rgb(37,99,235)', // Blue
|
|
419
|
-
briefLabelClaude: 'rgb(
|
|
419
|
+
briefLabelClaude: 'rgb(0,200,180)', // Xela teal
|
|
420
420
|
rainbow_red: 'rgb(235,95,87)',
|
|
421
421
|
rainbow_orange: 'rgb(245,139,87)',
|
|
422
422
|
rainbow_yellow: 'rgb(250,195,95)',
|
|
@@ -440,10 +440,10 @@ const lightDaltonizedTheme: Theme = {
|
|
|
440
440
|
const darkTheme: Theme = {
|
|
441
441
|
autoAccept: 'rgb(175,135,255)', // Electric violet
|
|
442
442
|
bashBorder: 'rgb(253,93,177)', // Bright pink
|
|
443
|
-
claude: 'rgb(
|
|
444
|
-
claudeShimmer: 'rgb(
|
|
445
|
-
claudeBlue_FOR_SYSTEM_SPINNER: 'rgb(
|
|
446
|
-
claudeBlueShimmer_FOR_SYSTEM_SPINNER: 'rgb(
|
|
443
|
+
claude: 'rgb(0,220,200)', // Xela teal (brighter for dark bg)
|
|
444
|
+
claudeShimmer: 'rgb(50,250,230)', // Lighter teal for shimmer
|
|
445
|
+
claudeBlue_FOR_SYSTEM_SPINNER: 'rgb(0,200,220)', // Cyan-teal for spinner
|
|
446
|
+
claudeBlueShimmer_FOR_SYSTEM_SPINNER: 'rgb(50,230,250)', // Lighter cyan-teal for spinner shimmer
|
|
447
447
|
permission: 'rgb(177,185,249)', // Light blue-purple
|
|
448
448
|
permissionShimmer: 'rgb(207,215,255)', // Lighter blue-purple for shimmer
|
|
449
449
|
planMode: 'rgb(72,150,140)', // Muted sage green
|
|
@@ -483,7 +483,7 @@ const darkTheme: Theme = {
|
|
|
483
483
|
// Chrome colors
|
|
484
484
|
chromeYellow: 'rgb(251,188,4)', // Chrome yellow
|
|
485
485
|
// TUI V2 colors
|
|
486
|
-
clawd_body: 'rgb(
|
|
486
|
+
clawd_body: 'rgb(0,200,180)',
|
|
487
487
|
clawd_background: 'rgb(0,0,0)',
|
|
488
488
|
userMessageBackground: 'rgb(55, 55, 55)', // Lighter grey for better visual contrast
|
|
489
489
|
userMessageBackgroundHover: 'rgb(70, 70, 70)',
|
|
@@ -497,7 +497,7 @@ const darkTheme: Theme = {
|
|
|
497
497
|
fastMode: 'rgb(255,120,20)', // Electric orange for dark bg
|
|
498
498
|
fastModeShimmer: 'rgb(255,165,70)', // Lighter orange for shimmer
|
|
499
499
|
briefLabelYou: 'rgb(122,180,232)', // Light blue
|
|
500
|
-
briefLabelClaude: 'rgb(
|
|
500
|
+
briefLabelClaude: 'rgb(0,220,200)', // Xela teal
|
|
501
501
|
rainbow_red: 'rgb(235,95,87)',
|
|
502
502
|
rainbow_orange: 'rgb(245,139,87)',
|
|
503
503
|
rainbow_yellow: 'rgb(250,195,95)',
|
|
@@ -521,8 +521,8 @@ const darkTheme: Theme = {
|
|
|
521
521
|
const darkDaltonizedTheme: Theme = {
|
|
522
522
|
autoAccept: 'rgb(175,135,255)', // Electric violet
|
|
523
523
|
bashBorder: 'rgb(51,153,255)', // Bright blue
|
|
524
|
-
claude: 'rgb(
|
|
525
|
-
claudeShimmer: 'rgb(
|
|
524
|
+
claude: 'rgb(0,200,180)', // Xela teal
|
|
525
|
+
claudeShimmer: 'rgb(50,230,210)', // Lighter teal for shimmer effect
|
|
526
526
|
claudeBlue_FOR_SYSTEM_SPINNER: 'rgb(153,204,255)', // Light blue for system spinner
|
|
527
527
|
claudeBlueShimmer_FOR_SYSTEM_SPINNER: 'rgb(183,224,255)', // Lighter blue for system spinner shimmer
|
|
528
528
|
permission: 'rgb(153,204,255)', // Light blue
|
|
@@ -564,7 +564,7 @@ const darkDaltonizedTheme: Theme = {
|
|
|
564
564
|
// Chrome colors
|
|
565
565
|
chromeYellow: 'rgb(251,188,4)', // Chrome yellow
|
|
566
566
|
// TUI V2 colors
|
|
567
|
-
clawd_body: 'rgb(
|
|
567
|
+
clawd_body: 'rgb(0,200,180)',
|
|
568
568
|
clawd_background: 'rgb(0,0,0)',
|
|
569
569
|
userMessageBackground: 'rgb(55, 55, 55)', // Lighter grey for better visual contrast
|
|
570
570
|
userMessageBackgroundHover: 'rgb(70, 70, 70)',
|
|
@@ -578,7 +578,7 @@ const darkDaltonizedTheme: Theme = {
|
|
|
578
578
|
fastMode: 'rgb(255,120,20)', // Electric orange for dark bg (color-blind safe)
|
|
579
579
|
fastModeShimmer: 'rgb(255,165,70)', // Lighter orange for shimmer
|
|
580
580
|
briefLabelYou: 'rgb(122,180,232)', // Light blue
|
|
581
|
-
briefLabelClaude: 'rgb(
|
|
581
|
+
briefLabelClaude: 'rgb(0,200,180)', // Xela teal
|
|
582
582
|
rainbow_red: 'rgb(235,95,87)',
|
|
583
583
|
rainbow_orange: 'rgb(245,139,87)',
|
|
584
584
|
rainbow_yellow: 'rgb(250,195,95)',
|