@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 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
+ }