@arcforge/theme 2.0.166
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/README.md +29 -0
- package/package.json +19 -0
- package/src/index.ts +113 -0
- package/src/themes.ts +90 -0
package/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# @arcforge/theme
|
|
2
|
+
|
|
3
|
+
The shared palette and syntax theme for the [Axon](https://axon.arclabs.it) agent runtime.
|
|
4
|
+
|
|
5
|
+
One source of truth for Arcnight — the Shiki-compatible TextMate theme — and the Axon UI
|
|
6
|
+
colour palette. Consumed by the terminal's highlighter, the Fleet extension's webviews,
|
|
7
|
+
and every other surface that has to look like Axon.
|
|
8
|
+
|
|
9
|
+
A theme is data, not a stylesheet: it ships as plain objects, so a consumer can hand it
|
|
10
|
+
to Shiki, read individual tokens for its own chrome, or render the same colours in a
|
|
11
|
+
terminal that has never heard of CSS.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @arcforge/theme
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Most people never install this directly. It arrives as a dependency of the Axon
|
|
18
|
+
framework when you scaffold an agent with `axon init`.
|
|
19
|
+
|
|
20
|
+
## Documentation
|
|
21
|
+
|
|
22
|
+
Full documentation is at **[axon.arclabs.it/docs/v2](https://axon.arclabs.it/docs/v2)**.
|
|
23
|
+
|
|
24
|
+
- [What is Axon?](https://axon.arclabs.it/docs/v2)
|
|
25
|
+
- [The TUI](https://axon.arclabs.it/docs/v2/tui)
|
|
26
|
+
|
|
27
|
+
## License
|
|
28
|
+
|
|
29
|
+
Proprietary. © ArcLabs
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@arcforge/theme",
|
|
3
|
+
"version": "2.0.166",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./src/index.ts",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./src/index.ts"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"src"
|
|
11
|
+
],
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"@types/bun": "latest",
|
|
14
|
+
"typescript": "^5"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@arcforge/types": "2.0.166"
|
|
18
|
+
}
|
|
19
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @arcforge/theme — shared syntax highlighting theme and UI palette.
|
|
3
|
+
*
|
|
4
|
+
* Source of truth for the Arcnight Shiki theme and the Axon UI color palette.
|
|
5
|
+
* Consumed by VTerm's highlighter, the debugger webview, and any future
|
|
6
|
+
* surface that needs consistent Axon styling.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// ── Arcnight — Shiki-compatible TextMate theme ──────────────────────────────
|
|
10
|
+
|
|
11
|
+
export const arcnight = {
|
|
12
|
+
name: "arcnight",
|
|
13
|
+
type: "dark" as const,
|
|
14
|
+
colors: {
|
|
15
|
+
"editor.background": "#070b10",
|
|
16
|
+
"editor.foreground": "#c7eaff",
|
|
17
|
+
},
|
|
18
|
+
tokenColors: [
|
|
19
|
+
{
|
|
20
|
+
scope: [
|
|
21
|
+
"variable",
|
|
22
|
+
"variable.other",
|
|
23
|
+
"variable.other.property",
|
|
24
|
+
"variable.other.object.property",
|
|
25
|
+
"variable.other.readwrite",
|
|
26
|
+
"meta.object-literal.key",
|
|
27
|
+
"support.variable.property",
|
|
28
|
+
],
|
|
29
|
+
settings: { foreground: "#7cceff" },
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
scope: [
|
|
33
|
+
"keyword",
|
|
34
|
+
"keyword.control",
|
|
35
|
+
"keyword.other",
|
|
36
|
+
"storage",
|
|
37
|
+
"storage.type",
|
|
38
|
+
"storage.modifier",
|
|
39
|
+
],
|
|
40
|
+
settings: { foreground: "#345a94" },
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
scope: ["constant.numeric", "number"],
|
|
44
|
+
settings: { foreground: "#326396" },
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
scope: ["entity.name.type", "entity.name.class", "constant", "support.type"],
|
|
48
|
+
settings: { foreground: "#3caed5" },
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
scope: ["entity.name.function", "support.function", "meta.function-call"],
|
|
52
|
+
settings: { foreground: "#3caed5" },
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
scope: ["string", "string.quoted", "string.template"],
|
|
56
|
+
settings: { foreground: "#4c6696" },
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
scope: ["keyword.operator", "punctuation.accessor"],
|
|
60
|
+
settings: { foreground: "#7cceff" },
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
scope: ["comment", "comment.line", "comment.block"],
|
|
64
|
+
settings: { foreground: "#585858", fontStyle: "italic" },
|
|
65
|
+
},
|
|
66
|
+
// ── AIR format scopes ────────────────────────────────────────────────
|
|
67
|
+
{ scope: ["punctuation.definition.tag.air"], settings: { foreground: "#2a4a6a" } },
|
|
68
|
+
{ scope: ["entity.name.tag.section.air"], settings: { foreground: "#345a94" } }, // meta, env, timeline
|
|
69
|
+
{ scope: ["entity.name.tag.turn.air"], settings: { foreground: "#3caed5" } }, // agent, user
|
|
70
|
+
{ scope: ["entity.name.tag.execute.air"], settings: { foreground: "#00B4D8" } }, // typescript, shell
|
|
71
|
+
{ scope: ["entity.name.tag.stdout.air"], settings: { foreground: "#4c6696" } }, // stdout
|
|
72
|
+
{ scope: ["entity.name.tag.prose.air"], settings: { foreground: "#7cceff" } }, // text, thinking
|
|
73
|
+
{ scope: ["entity.name.tag.signal.air"], settings: { foreground: "#3caed5" } }, // done
|
|
74
|
+
{ scope: ["entity.name.tag.env.air"], settings: { foreground: "#345a94" } }, // process, subagent
|
|
75
|
+
{ scope: ["entity.name.tag.system.air"], settings: { foreground: "#b43c3c" } }, // error, note
|
|
76
|
+
{ scope: ["entity.name.tag.state.air"], settings: { foreground: "#585858" } }, // unknown tags
|
|
77
|
+
{ scope: ["entity.other.attribute-name.air"], settings: { foreground: "#4c6696" } }, // attr names
|
|
78
|
+
{ scope: ["string.quoted.double.air"], settings: { foreground: "#326396" } }, // attr values
|
|
79
|
+
{ scope: ["constant.character.entity.air"], settings: { foreground: "#4c6696" } }, // < etc
|
|
80
|
+
],
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ── UI Palette — non-syntax colors used across Axon surfaces ────────────────
|
|
84
|
+
|
|
85
|
+
export const palette = {
|
|
86
|
+
primary: "#00B4D8",
|
|
87
|
+
userText: "#c8c8c8",
|
|
88
|
+
agentText: "#d2d2d2",
|
|
89
|
+
thinkingText: "#646464",
|
|
90
|
+
thinkingGlyph: "#3c3c3c",
|
|
91
|
+
toolLabel: "#828282",
|
|
92
|
+
output: "#505050",
|
|
93
|
+
railDim: "#3c3c3c",
|
|
94
|
+
railBright: "#505050",
|
|
95
|
+
omitted: "#3c3c3c",
|
|
96
|
+
error: "#b43c3c",
|
|
97
|
+
errorBright: "#f14c4c",
|
|
98
|
+
waiting: "#a07828",
|
|
99
|
+
denied: "#a03c3c",
|
|
100
|
+
codeLine: "#3c3c3c",
|
|
101
|
+
} as const
|
|
102
|
+
|
|
103
|
+
// ── Themes — the seven tokens every Axon surface draws from ─────────────────
|
|
104
|
+
export {
|
|
105
|
+
arcnightTheme,
|
|
106
|
+
BUILTIN_THEMES,
|
|
107
|
+
themeVariables,
|
|
108
|
+
type Theme,
|
|
109
|
+
type ThemeTokens,
|
|
110
|
+
type ThemeColor,
|
|
111
|
+
type ColorName,
|
|
112
|
+
type BundledSyntax,
|
|
113
|
+
} from "./themes"
|
package/src/themes.ts
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Themes — the seven tokens every Axon surface draws from.
|
|
3
|
+
*
|
|
4
|
+
* ── Why seven, and why closed ───────────────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* The TUI reached ~30 distinct hard-coded colours: four greys that nobody chose
|
|
7
|
+
* deliberately, five reds, two blues. Most of that variety is accidental rather
|
|
8
|
+
* than meaningful, and a theme API with a field per call site would preserve
|
|
9
|
+
* the accident forever — a "theme" would then mean thirty decisions, and no two
|
|
10
|
+
* themes would agree on what any of them were for.
|
|
11
|
+
*
|
|
12
|
+
* So the set is closed. A theme picks seven colours; every surface derives from
|
|
13
|
+
* them. That is what makes a theme portable: whatever an author writes, it
|
|
14
|
+
* lands on the same things in the same way.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Re-exported, not redefined.
|
|
19
|
+
*
|
|
20
|
+
* These types are the EXTENSION CONTRACT — a user's `theme.create()` is typed
|
|
21
|
+
* against the copy in `@arcforge/types/tui.ts`, which `axon prepare` writes
|
|
22
|
+
* into their frame. A second definition here would be the same shape twice,
|
|
23
|
+
* and the day they disagreed a theme would typecheck in a user's editor and be
|
|
24
|
+
* rejected by the terminal that loaded it.
|
|
25
|
+
*
|
|
26
|
+
* `BundledSyntax` in particular is generated from Shiki's own bundle, so
|
|
27
|
+
* duplicating it would mean duplicating the generator too.
|
|
28
|
+
*/
|
|
29
|
+
export type { ThemeColor, ColorName, ThemeTokens, Theme, BundledSyntax } from "@arcforge/types"
|
|
30
|
+
|
|
31
|
+
import type { Theme, ThemeTokens } from "@arcforge/types"
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Arcnight — the default, and the palette every Axon surface was built against.
|
|
35
|
+
*
|
|
36
|
+
* `primary` is the cyan the input rule, palette selection and header already
|
|
37
|
+
* use; `dim` is the grey that most secondary text collapsed to; `error` is the
|
|
38
|
+
* red the timeline's error rows use. Those three were already consistent —
|
|
39
|
+
* the rest of the variety is what this set replaces.
|
|
40
|
+
*/
|
|
41
|
+
export const arcnightTheme: Theme = {
|
|
42
|
+
name: "arcnight",
|
|
43
|
+
primary: "#00B4D8",
|
|
44
|
+
background: "transparent",
|
|
45
|
+
text: "#a8a8a8",
|
|
46
|
+
dim: "#6e6e6e",
|
|
47
|
+
warn: "#dca05a",
|
|
48
|
+
error: "#dc7878",
|
|
49
|
+
syntax: "arcnight",
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The themes Axon ships. A user's config adds to these; it never replaces them.
|
|
54
|
+
*
|
|
55
|
+
* ── Exactly one, deliberately ───────────────────────────────────────────────
|
|
56
|
+
*
|
|
57
|
+
* There was a second built-in — `ember` — added "purely so switching is
|
|
58
|
+
* testable: one theme cannot demonstrate that anything is actually themed."
|
|
59
|
+
* That reason expired the moment themes became installable: switching is now
|
|
60
|
+
* demonstrated by any published theme, and the built-in was doing nothing but
|
|
61
|
+
* occupying a name.
|
|
62
|
+
*
|
|
63
|
+
* And occupying a name is not free. `theme.create()` throws on a duplicate,
|
|
64
|
+
* and an extension registers at module scope — so a built-in squatting an
|
|
65
|
+
* obvious name does not merely shadow one theme, it throws partway through the
|
|
66
|
+
* file and costs every theme declared after it. `@axon/ember-theme` hit exactly
|
|
67
|
+
* that: the package could not register its own primary theme.
|
|
68
|
+
*
|
|
69
|
+
* So the rule this list follows: Axon ships the ONE theme it is designed
|
|
70
|
+
* around, and every other name belongs to whoever publishes it. A built-in
|
|
71
|
+
* added here is a name permanently taken from the ecosystem.
|
|
72
|
+
*/
|
|
73
|
+
export const BUILTIN_THEMES: readonly Theme[] = [arcnightTheme]
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Tokens as the CSS variables a stylesheet references.
|
|
77
|
+
*
|
|
78
|
+
* `syntax` is deliberately absent: it is a Shiki theme, not a colour, and is
|
|
79
|
+
* applied through the highlighter rather than by any `var()`.
|
|
80
|
+
*/
|
|
81
|
+
export function themeVariables(theme: ThemeTokens): Record<string, string> {
|
|
82
|
+
return {
|
|
83
|
+
primary: String(theme.primary),
|
|
84
|
+
background: String(theme.background),
|
|
85
|
+
text: String(theme.text),
|
|
86
|
+
dim: String(theme.dim),
|
|
87
|
+
warn: String(theme.warn),
|
|
88
|
+
error: String(theme.error),
|
|
89
|
+
}
|
|
90
|
+
}
|