everybuddy 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +184 -0
  3. package/dist/atlas/bundled.d.ts +15 -0
  4. package/dist/atlas/bundled.js +438 -0
  5. package/dist/atlas/bundled.js.map +1 -0
  6. package/dist/bones/rarity.d.ts +2 -0
  7. package/dist/bones/rarity.js +43 -0
  8. package/dist/bones/rarity.js.map +1 -0
  9. package/dist/bones/roll.d.ts +10 -0
  10. package/dist/bones/roll.js +71 -0
  11. package/dist/bones/roll.js.map +1 -0
  12. package/dist/bones/species.d.ts +1 -0
  13. package/dist/bones/species.js +3 -0
  14. package/dist/bones/species.js.map +1 -0
  15. package/dist/bones/stats.d.ts +6 -0
  16. package/dist/bones/stats.js +55 -0
  17. package/dist/bones/stats.js.map +1 -0
  18. package/dist/cli/attach.d.ts +5 -0
  19. package/dist/cli/attach.js +64 -0
  20. package/dist/cli/attach.js.map +1 -0
  21. package/dist/cli/card.d.ts +3 -0
  22. package/dist/cli/card.js +19 -0
  23. package/dist/cli/card.js.map +1 -0
  24. package/dist/cli/detach.d.ts +4 -0
  25. package/dist/cli/detach.js +36 -0
  26. package/dist/cli/detach.js.map +1 -0
  27. package/dist/cli/event.d.ts +7 -0
  28. package/dist/cli/event.js +35 -0
  29. package/dist/cli/event.js.map +1 -0
  30. package/dist/cli/hatch.d.ts +6 -0
  31. package/dist/cli/hatch.js +20 -0
  32. package/dist/cli/hatch.js.map +1 -0
  33. package/dist/cli/init.d.ts +2 -0
  34. package/dist/cli/init.js +76 -0
  35. package/dist/cli/init.js.map +1 -0
  36. package/dist/cli/install.d.ts +32 -0
  37. package/dist/cli/install.js +121 -0
  38. package/dist/cli/install.js.map +1 -0
  39. package/dist/cli/io.d.ts +9 -0
  40. package/dist/cli/io.js +35 -0
  41. package/dist/cli/io.js.map +1 -0
  42. package/dist/cli/setup.d.ts +26 -0
  43. package/dist/cli/setup.js +297 -0
  44. package/dist/cli/setup.js.map +1 -0
  45. package/dist/cli/sidecar.d.ts +5 -0
  46. package/dist/cli/sidecar.js +12 -0
  47. package/dist/cli/sidecar.js.map +1 -0
  48. package/dist/i18n/companion.d.ts +9 -0
  49. package/dist/i18n/companion.js +117 -0
  50. package/dist/i18n/companion.js.map +1 -0
  51. package/dist/i18n/ui.d.ts +67 -0
  52. package/dist/i18n/ui.js +270 -0
  53. package/dist/i18n/ui.js.map +1 -0
  54. package/dist/index.d.ts +2 -0
  55. package/dist/index.js +116 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/render/card.d.ts +10 -0
  58. package/dist/render/card.js +188 -0
  59. package/dist/render/card.js.map +1 -0
  60. package/dist/render/color.d.ts +5 -0
  61. package/dist/render/color.js +100 -0
  62. package/dist/render/color.js.map +1 -0
  63. package/dist/render/compose.d.ts +2 -0
  64. package/dist/render/compose.js +10 -0
  65. package/dist/render/compose.js.map +1 -0
  66. package/dist/render/gacha.d.ts +9 -0
  67. package/dist/render/gacha.js +322 -0
  68. package/dist/render/gacha.js.map +1 -0
  69. package/dist/render/sprites.d.ts +5 -0
  70. package/dist/render/sprites.js +316 -0
  71. package/dist/render/sprites.js.map +1 -0
  72. package/dist/runtime/observer.d.ts +73 -0
  73. package/dist/runtime/observer.js +448 -0
  74. package/dist/runtime/observer.js.map +1 -0
  75. package/dist/runtime/sidecar.d.ts +18 -0
  76. package/dist/runtime/sidecar.js +670 -0
  77. package/dist/runtime/sidecar.js.map +1 -0
  78. package/dist/runtime/socket.d.ts +6 -0
  79. package/dist/runtime/socket.js +47 -0
  80. package/dist/runtime/socket.js.map +1 -0
  81. package/dist/runtime/tmux.d.ts +41 -0
  82. package/dist/runtime/tmux.js +186 -0
  83. package/dist/runtime/tmux.js.map +1 -0
  84. package/dist/runtime/types.d.ts +96 -0
  85. package/dist/runtime/types.js +2 -0
  86. package/dist/runtime/types.js.map +1 -0
  87. package/dist/soul/hatch.d.ts +6 -0
  88. package/dist/soul/hatch.js +90 -0
  89. package/dist/soul/hatch.js.map +1 -0
  90. package/dist/soul/profile.d.ts +6 -0
  91. package/dist/soul/profile.js +48 -0
  92. package/dist/soul/profile.js.map +1 -0
  93. package/dist/soul/providers/anthropic.d.ts +17 -0
  94. package/dist/soul/providers/anthropic.js +105 -0
  95. package/dist/soul/providers/anthropic.js.map +1 -0
  96. package/dist/soul/providers/index.d.ts +10 -0
  97. package/dist/soul/providers/index.js +23 -0
  98. package/dist/soul/providers/index.js.map +1 -0
  99. package/dist/soul/providers/openai.d.ts +20 -0
  100. package/dist/soul/providers/openai.js +120 -0
  101. package/dist/soul/providers/openai.js.map +1 -0
  102. package/dist/soul/providers/types.d.ts +4 -0
  103. package/dist/soul/providers/types.js +2 -0
  104. package/dist/soul/providers/types.js.map +1 -0
  105. package/dist/storage/companion.d.ts +3 -0
  106. package/dist/storage/companion.js +155 -0
  107. package/dist/storage/companion.js.map +1 -0
  108. package/dist/storage/config.d.ts +36 -0
  109. package/dist/storage/config.js +220 -0
  110. package/dist/storage/config.js.map +1 -0
  111. package/dist/storage/paths.d.ts +3 -0
  112. package/dist/storage/paths.js +12 -0
  113. package/dist/storage/paths.js.map +1 -0
  114. package/dist/types/companion.d.ts +84 -0
  115. package/dist/types/companion.js +2 -0
  116. package/dist/types/companion.js.map +1 -0
  117. package/dist/types/onboarding.d.ts +12 -0
  118. package/dist/types/onboarding.js +2 -0
  119. package/dist/types/onboarding.js.map +1 -0
  120. package/package.json +52 -0
@@ -0,0 +1,17 @@
1
+ import type { AIProvider } from "./types.js";
2
+ export interface AnthropicProviderOptions {
3
+ apiKey: string;
4
+ model: string;
5
+ baseUrl?: string | undefined;
6
+ systemPrompt?: string | undefined;
7
+ requestTimeoutMs?: number | undefined;
8
+ }
9
+ export declare class AnthropicProvider implements AIProvider {
10
+ readonly modelId: string;
11
+ private readonly apiKey;
12
+ private readonly baseUrl;
13
+ private readonly systemPrompt;
14
+ private readonly requestTimeoutMs;
15
+ constructor(options: AnthropicProviderOptions);
16
+ complete(prompt: string): Promise<string>;
17
+ }
@@ -0,0 +1,105 @@
1
+ const DEFAULT_BASE_URL = "https://api.anthropic.com";
2
+ const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
3
+ const ANTHROPIC_VERSION = "2023-06-01";
4
+ const DEFAULT_SYSTEM_PROMPT = "You create concise terminal companion metadata. Follow the user request exactly and return only the requested JSON.";
5
+ export class AnthropicProvider {
6
+ modelId;
7
+ apiKey;
8
+ baseUrl;
9
+ systemPrompt;
10
+ requestTimeoutMs;
11
+ constructor(options) {
12
+ this.modelId = options.model;
13
+ this.apiKey = options.apiKey;
14
+ this.baseUrl = normalizeBaseUrl(options.baseUrl);
15
+ this.systemPrompt = options.systemPrompt?.trim() || DEFAULT_SYSTEM_PROMPT;
16
+ this.requestTimeoutMs = normalizeTimeoutMs(options.requestTimeoutMs);
17
+ }
18
+ async complete(prompt) {
19
+ const controller = new AbortController();
20
+ const timeout = setTimeout(() => {
21
+ controller.abort();
22
+ }, this.requestTimeoutMs);
23
+ let response;
24
+ try {
25
+ response = await fetch(`${this.baseUrl}/v1/messages`, {
26
+ method: "POST",
27
+ headers: {
28
+ "Content-Type": "application/json",
29
+ "x-api-key": this.apiKey,
30
+ "anthropic-version": ANTHROPIC_VERSION,
31
+ },
32
+ body: JSON.stringify({
33
+ model: this.modelId,
34
+ max_tokens: 1024,
35
+ system: this.systemPrompt,
36
+ messages: [{ role: "user", content: prompt }],
37
+ }),
38
+ signal: controller.signal,
39
+ });
40
+ }
41
+ catch (error) {
42
+ if (isAbortError(error)) {
43
+ throw new Error(`Provider request timed out after ${Math.ceil(this.requestTimeoutMs / 1000)}s.`);
44
+ }
45
+ throw new Error(`Provider request failed: ${getErrorMessage(error)}`);
46
+ }
47
+ finally {
48
+ clearTimeout(timeout);
49
+ }
50
+ const payload = (await response.json().catch(async () => {
51
+ const text = await response.text();
52
+ throw new Error(`Provider returned invalid JSON: ${text}`);
53
+ }));
54
+ if (!response.ok) {
55
+ throw new Error(`Provider request failed (${response.status} ${response.statusText}): ${extractErrorMessage(payload)}`);
56
+ }
57
+ const content = payload.content;
58
+ const text = Array.isArray(content) &&
59
+ content.length > 0 &&
60
+ typeof content[0] === "object" &&
61
+ content[0] !== null &&
62
+ "text" in content[0] &&
63
+ typeof content[0].text === "string"
64
+ ? content[0].text
65
+ : undefined;
66
+ if (!text || text.trim().length === 0) {
67
+ throw new Error("Provider returned an empty response.");
68
+ }
69
+ return text;
70
+ }
71
+ }
72
+ function normalizeBaseUrl(value) {
73
+ const normalized = value?.trim() || DEFAULT_BASE_URL;
74
+ return normalized.replace(/\/+$/, "");
75
+ }
76
+ function normalizeTimeoutMs(value) {
77
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
78
+ return DEFAULT_REQUEST_TIMEOUT_MS;
79
+ }
80
+ return Math.floor(value);
81
+ }
82
+ function isAbortError(error) {
83
+ return ((error instanceof DOMException && error.name === "AbortError") ||
84
+ (typeof error === "object" &&
85
+ error !== null &&
86
+ "name" in error &&
87
+ error.name === "AbortError"));
88
+ }
89
+ function extractErrorMessage(value) {
90
+ if (typeof value === "object" && value !== null) {
91
+ const record = value;
92
+ const error = record.error;
93
+ if (typeof error === "object" && error !== null && "message" in error) {
94
+ const message = error.message;
95
+ if (typeof message === "string" && message.trim().length > 0) {
96
+ return message;
97
+ }
98
+ }
99
+ }
100
+ return "unknown provider error";
101
+ }
102
+ function getErrorMessage(error) {
103
+ return error instanceof Error ? error.message : String(error);
104
+ }
105
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/soul/providers/anthropic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { BuddyProvider } from "../../types/companion.js";
2
+ import type { AIProvider } from "./types.js";
3
+ export interface CreateProviderParams {
4
+ provider: BuddyProvider;
5
+ apiKey: string;
6
+ model: string;
7
+ baseUrl?: string | undefined;
8
+ systemPrompt?: string | undefined;
9
+ }
10
+ export declare function createProvider(params: CreateProviderParams): AIProvider;
@@ -0,0 +1,23 @@
1
+ import { AnthropicProvider } from "./anthropic.js";
2
+ import { OpenAICompatibleProvider } from "./openai.js";
3
+ export function createProvider(params) {
4
+ switch (params.provider) {
5
+ case "anthropic":
6
+ return new AnthropicProvider({
7
+ apiKey: params.apiKey,
8
+ model: params.model,
9
+ baseUrl: params.baseUrl,
10
+ systemPrompt: params.systemPrompt,
11
+ });
12
+ case "openai":
13
+ case "custom":
14
+ default:
15
+ return new OpenAICompatibleProvider({
16
+ apiKey: params.apiKey,
17
+ model: params.model,
18
+ baseUrl: params.baseUrl,
19
+ systemPrompt: params.systemPrompt,
20
+ });
21
+ }
22
+ }
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/soul/providers/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAWvD,MAAM,UAAU,cAAc,CAAC,MAA4B;IACzD,QAAQ,MAAM,CAAC,QAAQ,EAAE,CAAC;QACxB,KAAK,WAAW;YACd,OAAO,IAAI,iBAAiB,CAAC;gBAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,YAAY,EAAE,MAAM,CAAC,YAAY;aAClC,CAAC,CAAC;QACL,KAAK,QAAQ,CAAC;QACd,KAAK,QAAQ,CAAC;QACd;YACE,OAAO,IAAI,wBAAwB,CAAC;gBAClC,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,YAAY,EAAE,MAAM,CAAC,YAAY;aAClC,CAAC,CAAC;IACP,CAAC;AACH,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { AIProvider } from "./types.js";
2
+ export interface OpenAICompatibleProviderOptions {
3
+ apiKey: string;
4
+ model: string;
5
+ baseUrl?: string | undefined;
6
+ systemPrompt?: string | undefined;
7
+ requestTimeoutMs?: number | undefined;
8
+ }
9
+ export declare const DEFAULT_SYSTEM_PROMPT = "You create concise terminal companion metadata. Follow the user request exactly and return only the requested JSON.";
10
+ export declare class OpenAICompatibleProvider implements AIProvider {
11
+ readonly modelId: string;
12
+ private readonly apiKey;
13
+ private readonly baseUrl;
14
+ private readonly systemPrompt;
15
+ private readonly requestTimeoutMs;
16
+ private readonly disableThinking;
17
+ constructor(options: OpenAICompatibleProviderOptions);
18
+ complete(prompt: string): Promise<string>;
19
+ }
20
+ export declare function shouldDisableThinking(baseUrl: string): boolean;
@@ -0,0 +1,120 @@
1
+ const DEFAULT_BASE_URL = "https://api.openai.com/v1";
2
+ const DEFAULT_REQUEST_TIMEOUT_MS = 20_000;
3
+ export const DEFAULT_SYSTEM_PROMPT = "You create concise terminal companion metadata. Follow the user request exactly and return only the requested JSON.";
4
+ export class OpenAICompatibleProvider {
5
+ modelId;
6
+ apiKey;
7
+ baseUrl;
8
+ systemPrompt;
9
+ requestTimeoutMs;
10
+ disableThinking;
11
+ constructor(options) {
12
+ this.modelId = options.model;
13
+ this.apiKey = options.apiKey;
14
+ this.baseUrl = normalizeBaseUrl(options.baseUrl);
15
+ this.systemPrompt = options.systemPrompt?.trim() || DEFAULT_SYSTEM_PROMPT;
16
+ this.requestTimeoutMs = normalizeTimeoutMs(options.requestTimeoutMs);
17
+ this.disableThinking = shouldDisableThinking(this.baseUrl);
18
+ }
19
+ async complete(prompt) {
20
+ const controller = new AbortController();
21
+ const timeout = setTimeout(() => {
22
+ controller.abort();
23
+ }, this.requestTimeoutMs);
24
+ const requestBody = {
25
+ model: this.modelId,
26
+ messages: [
27
+ { role: "system", content: this.systemPrompt },
28
+ { role: "user", content: prompt },
29
+ ],
30
+ };
31
+ if (this.disableThinking) {
32
+ requestBody.enable_thinking = false;
33
+ }
34
+ let response;
35
+ try {
36
+ response = await fetch(`${this.baseUrl}/chat/completions`, {
37
+ method: "POST",
38
+ headers: {
39
+ "Content-Type": "application/json",
40
+ Authorization: `Bearer ${this.apiKey}`,
41
+ },
42
+ body: JSON.stringify(requestBody),
43
+ signal: controller.signal,
44
+ });
45
+ }
46
+ catch (error) {
47
+ if (isAbortError(error)) {
48
+ throw new Error(`Provider request timed out after ${Math.ceil(this.requestTimeoutMs / 1000)}s.`);
49
+ }
50
+ throw new Error(`Provider request failed: ${getErrorMessage(error)}`);
51
+ }
52
+ finally {
53
+ clearTimeout(timeout);
54
+ }
55
+ const payload = (await response.json().catch(async () => {
56
+ const text = await response.text();
57
+ throw new Error(`Provider returned invalid JSON: ${text}`);
58
+ }));
59
+ if (!response.ok) {
60
+ throw new Error(`Provider request failed (${response.status} ${response.statusText}): ${extractErrorMessage(payload)}`);
61
+ }
62
+ const choices = payload.choices;
63
+ const content = Array.isArray(choices) &&
64
+ typeof choices[0] === "object" &&
65
+ choices[0] !== null &&
66
+ "message" in choices[0] &&
67
+ typeof choices[0].message === "object" &&
68
+ choices[0].message !== null &&
69
+ "content" in choices[0].message
70
+ ? choices[0].message.content
71
+ : undefined;
72
+ if (typeof content !== "string" || content.trim().length === 0) {
73
+ throw new Error("Provider returned an empty response.");
74
+ }
75
+ return content;
76
+ }
77
+ }
78
+ function normalizeBaseUrl(value) {
79
+ const normalized = value?.trim() || DEFAULT_BASE_URL;
80
+ return normalized.replace(/\/+$/, "");
81
+ }
82
+ function normalizeTimeoutMs(value) {
83
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
84
+ return DEFAULT_REQUEST_TIMEOUT_MS;
85
+ }
86
+ return Math.floor(value);
87
+ }
88
+ export function shouldDisableThinking(baseUrl) {
89
+ try {
90
+ const url = new URL(baseUrl);
91
+ return url.hostname.endsWith("dashscope.aliyuncs.com");
92
+ }
93
+ catch {
94
+ return false;
95
+ }
96
+ }
97
+ function isAbortError(error) {
98
+ return ((error instanceof DOMException && error.name === "AbortError") ||
99
+ (typeof error === "object" &&
100
+ error !== null &&
101
+ "name" in error &&
102
+ error.name === "AbortError"));
103
+ }
104
+ function extractErrorMessage(value) {
105
+ if (typeof value === "object" && value !== null) {
106
+ const record = value;
107
+ const error = record.error;
108
+ if (typeof error === "object" && error !== null && "message" in error) {
109
+ const message = error.message;
110
+ if (typeof message === "string" && message.trim().length > 0) {
111
+ return message;
112
+ }
113
+ }
114
+ }
115
+ return "unknown provider error";
116
+ }
117
+ function getErrorMessage(error) {
118
+ return error instanceof Error ? error.message : String(error);
119
+ }
120
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/soul/providers/openai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export interface AIProvider {
2
+ readonly modelId: string;
3
+ complete(prompt: string): Promise<string>;
4
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/soul/providers/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { CompanionRecord } from "../types/companion.js";
2
+ export declare function readCompanionRecord(storageDir?: string): Promise<CompanionRecord | null>;
3
+ export declare function writeCompanionRecord(record: CompanionRecord, storageDir?: string): Promise<void>;
@@ -0,0 +1,155 @@
1
+ import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { DEFAULT_OBSERVER_PROFILE, parseOptionalObserverProfile } from "../soul/profile.js";
4
+ import { companionFilePath, defaultStorageDir } from "./paths.js";
5
+ export async function readCompanionRecord(storageDir = defaultStorageDir()) {
6
+ const targetPath = companionFilePath(storageDir);
7
+ try {
8
+ const raw = await readFile(targetPath, "utf8");
9
+ const parsed = JSON.parse(raw);
10
+ return parseCompanionRecord(parsed);
11
+ }
12
+ catch (error) {
13
+ if (isMissingFileError(error)) {
14
+ return null;
15
+ }
16
+ throw new Error(`Failed to read companion at ${targetPath}: ${getErrorMessage(error)}`);
17
+ }
18
+ }
19
+ export async function writeCompanionRecord(record, storageDir = defaultStorageDir()) {
20
+ const targetPath = companionFilePath(storageDir);
21
+ const tempPath = path.join(storageDir, `.companion.${process.pid}.${Date.now().toString(36)}.tmp`);
22
+ const payload = JSON.stringify(record, null, 2);
23
+ await mkdir(storageDir, { recursive: true });
24
+ await writeFile(tempPath, payload, "utf8");
25
+ await rename(tempPath, targetPath);
26
+ }
27
+ function parseCompanionRecord(value) {
28
+ if (!isPlainObject(value)) {
29
+ throw new Error("Companion file must contain a JSON object.");
30
+ }
31
+ const { templateId, userId, bones, soul, createdAt } = value;
32
+ if (templateId !== undefined && (typeof templateId !== "string" || templateId.trim().length === 0)) {
33
+ throw new Error("Companion `templateId` must be a non-empty string when present.");
34
+ }
35
+ if (typeof userId !== "string" || userId.trim().length === 0) {
36
+ throw new Error("Companion `userId` must be a non-empty string.");
37
+ }
38
+ if (typeof createdAt !== "string" || createdAt.trim().length === 0) {
39
+ throw new Error("Companion `createdAt` must be a non-empty string.");
40
+ }
41
+ return {
42
+ ...(typeof templateId === "string" ? { templateId: templateId.trim() } : {}),
43
+ userId,
44
+ bones: parseCompanionBones(bones),
45
+ soul: parseCompanionSoul(soul),
46
+ createdAt,
47
+ };
48
+ }
49
+ function parseCompanionBones(value) {
50
+ if (!isPlainObject(value)) {
51
+ throw new Error("Companion `bones` must be an object.");
52
+ }
53
+ const { userId, species, rarity, eye, hat, stats, color, shiny } = value;
54
+ if (typeof userId !== "string" || userId.trim().length === 0) {
55
+ throw new Error("Companion bones `userId` must be a non-empty string.");
56
+ }
57
+ if (typeof species !== "string" || species.trim().length === 0) {
58
+ throw new Error("Companion bones `species` must be a non-empty string.");
59
+ }
60
+ if (typeof eye !== "string" || eye.trim().length === 0) {
61
+ throw new Error("Companion bones `eye` must be a non-empty string.");
62
+ }
63
+ if (typeof hat !== "string" || hat.trim().length === 0) {
64
+ throw new Error("Companion bones `hat` must be a non-empty string.");
65
+ }
66
+ if (typeof shiny !== "boolean") {
67
+ throw new Error("Companion bones `shiny` must be a boolean.");
68
+ }
69
+ return {
70
+ userId,
71
+ species,
72
+ rarity: parseRarity(rarity),
73
+ eye,
74
+ hat,
75
+ stats: parseStatBlock(stats),
76
+ color: parseColorPalette(color),
77
+ shiny,
78
+ };
79
+ }
80
+ function parseCompanionSoul(value) {
81
+ if (!isPlainObject(value)) {
82
+ throw new Error("Companion `soul` must be an object.");
83
+ }
84
+ const { name, tagline, personality, modelUsed } = value;
85
+ const observerProfile = parseOptionalObserverProfile(value.observerProfile);
86
+ if (typeof name !== "string" || name.trim().length === 0) {
87
+ throw new Error("Companion soul `name` must be a non-empty string.");
88
+ }
89
+ if (tagline !== undefined && (typeof tagline !== "string" || tagline.trim().length === 0)) {
90
+ throw new Error("Companion soul `tagline` must be a non-empty string when present.");
91
+ }
92
+ if (typeof personality !== "string" || personality.trim().length === 0) {
93
+ throw new Error("Companion soul `personality` must be a non-empty string.");
94
+ }
95
+ if (typeof modelUsed !== "string" || modelUsed.trim().length === 0) {
96
+ throw new Error("Companion soul `modelUsed` must be a non-empty string.");
97
+ }
98
+ return {
99
+ name: name.trim(),
100
+ ...(typeof tagline === "string" ? { tagline: tagline.trim() } : {}),
101
+ personality: personality.trim(),
102
+ observerProfile: observerProfile ?? { ...DEFAULT_OBSERVER_PROFILE },
103
+ modelUsed: modelUsed.trim(),
104
+ };
105
+ }
106
+ function parseRarity(value) {
107
+ if (!isPlainObject(value)) {
108
+ throw new Error("Companion rarity must be an object.");
109
+ }
110
+ const { tier, name, stars, color, weight, floor } = value;
111
+ if (typeof tier !== "number" ||
112
+ typeof name !== "string" ||
113
+ typeof stars !== "string" ||
114
+ typeof color !== "string" ||
115
+ typeof weight !== "number" ||
116
+ typeof floor !== "number") {
117
+ throw new Error("Companion rarity is invalid.");
118
+ }
119
+ return { tier, name, stars, color, weight, floor };
120
+ }
121
+ function parseStatBlock(value) {
122
+ if (!isPlainObject(value)) {
123
+ throw new Error("Companion stats must be an object.");
124
+ }
125
+ const statNames = ["GRIT", "FOCUS", "CHAOS", "WIT", "SASS"];
126
+ const stats = {};
127
+ for (const statName of statNames) {
128
+ const statValue = value[statName];
129
+ if (typeof statValue !== "number") {
130
+ throw new Error(`Companion stat ${statName} must be a number.`);
131
+ }
132
+ stats[statName] = statValue;
133
+ }
134
+ return stats;
135
+ }
136
+ function parseColorPalette(value) {
137
+ if (!isPlainObject(value)) {
138
+ throw new Error("Companion color palette must be an object.");
139
+ }
140
+ const { primary, accent } = value;
141
+ if (typeof primary !== "string" || typeof accent !== "string") {
142
+ throw new Error("Companion color palette is invalid.");
143
+ }
144
+ return { primary, accent };
145
+ }
146
+ function isPlainObject(value) {
147
+ return typeof value === "object" && value !== null && !Array.isArray(value);
148
+ }
149
+ function isMissingFileError(error) {
150
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
151
+ }
152
+ function getErrorMessage(error) {
153
+ return error instanceof Error ? error.message : String(error);
154
+ }
155
+ //# sourceMappingURL=companion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"companion.js","sourceRoot":"","sources":["../../src/storage/companion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { BuddyConfig, HatchReadyConfig, ResolvedBuddyConfig } from "../types/companion.js";
2
+ export declare const DEFAULT_OPENAI_BASE_URL = "https://coding.dashscope.aliyuncs.com/v1";
3
+ export declare const DEFAULT_OPENAI_MODEL = "qwen3.5-plus";
4
+ export declare const DEFAULT_OPENAI_OBSERVER_MODEL = "qwen3-coder-next";
5
+ export declare const DEFAULT_ANTHROPIC_BASE_URL = "https://api.anthropic.com";
6
+ export declare const DEFAULT_ANTHROPIC_MODEL = "claude-haiku-4-5-20251001";
7
+ export declare const DEFAULT_ANTHROPIC_OBSERVER_MODEL = "claude-haiku-4-5-20251001";
8
+ export declare const PROVIDER_DEFAULTS: {
9
+ readonly openai: {
10
+ readonly baseUrl: "https://coding.dashscope.aliyuncs.com/v1";
11
+ readonly model: "qwen3.5-plus";
12
+ readonly observerModel: "qwen3-coder-next";
13
+ };
14
+ readonly anthropic: {
15
+ readonly baseUrl: "https://api.anthropic.com";
16
+ readonly model: "claude-haiku-4-5-20251001";
17
+ readonly observerModel: "claude-haiku-4-5-20251001";
18
+ };
19
+ readonly custom: {
20
+ readonly baseUrl: string | undefined;
21
+ readonly model: string | undefined;
22
+ readonly observerModel: string | undefined;
23
+ };
24
+ };
25
+ export interface ResolveBuddyConfigOptions {
26
+ model?: string | undefined;
27
+ apiKey?: string | undefined;
28
+ baseUrl?: string | undefined;
29
+ storageDir?: string | undefined;
30
+ }
31
+ export declare function resolveBuddyConfig(options?: ResolveBuddyConfigOptions): Promise<ResolvedBuddyConfig>;
32
+ export declare function assertHatchReadyConfig(config: ResolvedBuddyConfig): HatchReadyConfig;
33
+ export declare function resolveUserId(cliUserId?: string): string;
34
+ export declare function readBuddyConfigFile(storageDir?: string): Promise<BuddyConfig>;
35
+ export declare function writeBuddyConfigFile(config: BuddyConfig, storageDir?: string): Promise<void>;
36
+ export declare function updateBuddyConfigFile(updates: BuddyConfig, storageDir?: string): Promise<BuddyConfig>;