@joingonka/setup 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 (51) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +46 -0
  3. package/dist/adapters/claude-code.d.ts +3 -0
  4. package/dist/adapters/claude-code.d.ts.map +1 -0
  5. package/dist/adapters/claude-code.js +70 -0
  6. package/dist/adapters/claude-code.js.map +1 -0
  7. package/dist/adapters/cline.d.ts +3 -0
  8. package/dist/adapters/cline.d.ts.map +1 -0
  9. package/dist/adapters/cline.js +43 -0
  10. package/dist/adapters/cline.js.map +1 -0
  11. package/dist/adapters/openclaw.d.ts +3 -0
  12. package/dist/adapters/openclaw.d.ts.map +1 -0
  13. package/dist/adapters/openclaw.js +159 -0
  14. package/dist/adapters/openclaw.js.map +1 -0
  15. package/dist/adapters/registry.d.ts +24 -0
  16. package/dist/adapters/registry.d.ts.map +1 -0
  17. package/dist/adapters/registry.js +25 -0
  18. package/dist/adapters/registry.js.map +1 -0
  19. package/dist/adapters/types.d.ts +51 -0
  20. package/dist/adapters/types.d.ts.map +1 -0
  21. package/dist/adapters/types.js +10 -0
  22. package/dist/adapters/types.js.map +1 -0
  23. package/dist/cli.d.ts +3 -0
  24. package/dist/cli.d.ts.map +1 -0
  25. package/dist/cli.js +55 -0
  26. package/dist/cli.js.map +1 -0
  27. package/dist/constants.d.ts +98 -0
  28. package/dist/constants.d.ts.map +1 -0
  29. package/dist/constants.js +117 -0
  30. package/dist/constants.js.map +1 -0
  31. package/dist/core/fs-ops.d.ts +28 -0
  32. package/dist/core/fs-ops.d.ts.map +1 -0
  33. package/dist/core/fs-ops.js +63 -0
  34. package/dist/core/fs-ops.js.map +1 -0
  35. package/dist/core/merge.d.ts +62 -0
  36. package/dist/core/merge.d.ts.map +1 -0
  37. package/dist/core/merge.js +98 -0
  38. package/dist/core/merge.js.map +1 -0
  39. package/dist/core/prompt.d.ts +8 -0
  40. package/dist/core/prompt.d.ts.map +1 -0
  41. package/dist/core/prompt.js +29 -0
  42. package/dist/core/prompt.js.map +1 -0
  43. package/dist/core/validate.d.ts +12 -0
  44. package/dist/core/validate.d.ts.map +1 -0
  45. package/dist/core/validate.js +22 -0
  46. package/dist/core/validate.js.map +1 -0
  47. package/dist/run.d.ts +24 -0
  48. package/dist/run.d.ts.map +1 -0
  49. package/dist/run.js +65 -0
  50. package/dist/run.js.map +1 -0
  51. package/package.json +53 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/core/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,mDAAmD;AACnD,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,SAAS,CAAC,QAAiB,EAAE,KAAiB;IAC5D,uEAAuE;IACvE,MAAM,IAAI,GAAe,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAEjE,MAAM,MAAM,GAAe,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC;IAEjD,+CAA+C;IAC/C,IAAI,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,CAAC,GAAG,GAAG,EAAE,GAAG,WAAW,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;IAChD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,aAAa,CAAC,IAAa,EAAE,KAAiB;IAC5D,MAAM,GAAG,GAAe,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/D,KAAK,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACtD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,mEAAmE;YACnE,SAAS;QACX,CAAC;QACD,MAAM,SAAS,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,aAAa,CAAC,SAAS,CAAC,IAAI,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC;YAC1D,GAAG,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,UAAU,CAAC,KAAgB,EAAE,IAAiC;IAC5E,MAAM,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IACvB,MAAM,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;IACnF,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACf,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;QACtB,OAAO,GAAG,CAAC;IACb,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAe,CAAC;IACxC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,IAAI,EAAE,CAAC;IACpC,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Запрос API-ключа через password-промпт (маскируется, не попадает
3
+ * в историю stdin). Валидация — тот же validateApiKey, что и для env-ключа.
4
+ */
5
+ export declare function askApiKey(): Promise<string>;
6
+ /** Выбор инструмента из меню (список берётся из реестра адаптеров). */
7
+ export declare function askTool(): Promise<string>;
8
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/core/prompt.ts"],"names":[],"mappings":"AAWA;;;GAGG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAMjD;AAED,uEAAuE;AACvE,wBAAsB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAK/C"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Интерактивные промпты поверх @inquirer/prompts.
3
+ *
4
+ * Вынесены в отдельный модуль, чтобы оркестратор (run.ts) принимал их как
5
+ * зависимости и тесты могли подменять промпты spy-функциями без реального
6
+ * stdin. В проде CLI передаёт именно эти реализации.
7
+ */
8
+ import { password, select } from '@inquirer/prompts';
9
+ import { validateApiKey } from './validate.js';
10
+ import { listTools } from '../adapters/registry.js';
11
+ /**
12
+ * Запрос API-ключа через password-промпт (маскируется, не попадает
13
+ * в историю stdin). Валидация — тот же validateApiKey, что и для env-ключа.
14
+ */
15
+ export async function askApiKey() {
16
+ return password({
17
+ message: 'Enter your JoinGonka API key (jg-...):',
18
+ mask: '*',
19
+ validate: validateApiKey,
20
+ });
21
+ }
22
+ /** Выбор инструмента из меню (список берётся из реестра адаптеров). */
23
+ export async function askTool() {
24
+ return select({
25
+ message: 'Which tool do you want to configure?',
26
+ choices: listTools(),
27
+ });
28
+ }
29
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/core/prompt.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,OAAO,QAAQ,CAAC;QACd,OAAO,EAAE,wCAAwC;QACjD,IAAI,EAAE,GAAG;QACT,QAAQ,EAAE,cAAc;KACzB,CAAC,CAAC;AACL,CAAC;AAED,uEAAuE;AACvE,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,OAAO,MAAM,CAAC;QACZ,OAAO,EAAE,sCAAsC;QAC/C,OAAO,EAAE,SAAS,EAAE;KACrB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Валидация JoinGonka API-ключа.
3
+ *
4
+ * Все ключи JoinGonka имеют префикс `jg-`. Проверяем именно префикс,
5
+ * а не просто наличие подстроки, чтобы отсеять чужие форматы ключей
6
+ * (sk-..., и т.п.) до записи их в конфиг.
7
+ *
8
+ * Сигнатура `true | string` совместима с опцией `validate`
9
+ * из @inquirer/prompts — то же значение используется и в password-промпте.
10
+ */
11
+ export declare function validateApiKey(value: string): true | string;
12
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/core/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAU3D"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Валидация JoinGonka API-ключа.
3
+ *
4
+ * Все ключи JoinGonka имеют префикс `jg-`. Проверяем именно префикс,
5
+ * а не просто наличие подстроки, чтобы отсеять чужие форматы ключей
6
+ * (sk-..., и т.п.) до записи их в конфиг.
7
+ *
8
+ * Сигнатура `true | string` совместима с опцией `validate`
9
+ * из @inquirer/prompts — то же значение используется и в password-промпте.
10
+ */
11
+ export function validateApiKey(value) {
12
+ // Обрезаем пробелы: ввод вида " " не должен считаться валидным
13
+ const v = (value ?? '').trim();
14
+ if (!v) {
15
+ return 'API key is required';
16
+ }
17
+ if (!v.startsWith('jg-')) {
18
+ return 'API key must start with jg-';
19
+ }
20
+ return true;
21
+ }
22
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/core/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,iEAAiE;IACjE,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/B,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IACD,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,6BAA6B,CAAC;IACvC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
package/dist/run.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ import type { ApplyResult, Scope } from './adapters/types.js';
2
+ /** Опции запуска (из CLI-аргументов). */
3
+ export interface RunOptions {
4
+ /** Идентификатор инструмента; если не задан — спросим интерактивно. */
5
+ tool?: string;
6
+ /** 'user' (глобально) или 'local' (в проекте). По умолчанию 'user'. */
7
+ scope?: Scope;
8
+ /** Модель: undefined → default; 'kimi' → Kimi; иначе трактуется как явный id. */
9
+ model?: string;
10
+ /** Неинтерактивный режим: ключ берётся из env, промпты запрещены. */
11
+ nonInteractive?: boolean;
12
+ }
13
+ /** Инъектируемые промпты (в проде — реализации из core/prompt.ts). */
14
+ export interface RunDeps {
15
+ askTool: () => Promise<string>;
16
+ askApiKey: () => Promise<string>;
17
+ }
18
+ /** Что вернул запуск — для вывода в CLI. */
19
+ export interface RunOutcome {
20
+ toolId: string;
21
+ result: ApplyResult;
22
+ }
23
+ export declare function run(options: RunOptions, deps: RunDeps): Promise<RunOutcome>;
24
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAE9D,yCAAyC;AACzC,MAAM,WAAW,UAAU;IACzB,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,sEAAsE;AACtE,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAClC;AAED,4CAA4C;AAC5C,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;CACrB;AAiBD,wBAAsB,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAuCjF"}
package/dist/run.js ADDED
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Оркестратор установки.
3
+ *
4
+ * Склеивает шаги, не зная деталей конкретных инструментов:
5
+ * 1. выбрать инструмент (явный --tool или интерактивный select);
6
+ * 2. получить API-ключ (из env в non-interactive, иначе password-промпт);
7
+ * 3. определить модель (default / kimi / явный id);
8
+ * 4. вызвать adapter.apply().
9
+ *
10
+ * Промпты инъектируются через deps — это делает оркестратор полностью
11
+ * тестируемым (spy-функции) и отвязывает его от @inquirer/prompts.
12
+ */
13
+ import { DEFAULT_MODEL, KIMI_MODEL } from './constants.js';
14
+ import { validateApiKey } from './core/validate.js';
15
+ import { getAdapter, listTools } from './adapters/registry.js';
16
+ /**
17
+ * Разрешает значение модели:
18
+ * - undefined / пусто → DEFAULT_MODEL;
19
+ * - 'kimi' (регистронезависимо) → KIMI_MODEL;
20
+ * - любое другое → используется как явный id модели.
21
+ */
22
+ function resolveModel(model) {
23
+ if (!model)
24
+ return DEFAULT_MODEL;
25
+ if (model.toLowerCase() === 'kimi')
26
+ return KIMI_MODEL;
27
+ return model;
28
+ }
29
+ /** Имя env-переменной с ключом для non-interactive режима. */
30
+ const API_KEY_ENV = 'JOINGONKA_API_KEY';
31
+ export async function run(options, deps) {
32
+ const scope = options.scope ?? 'user';
33
+ // 1. Выбор инструмента: явный --tool либо интерактивный select.
34
+ const toolId = options.tool ?? (await deps.askTool());
35
+ const adapter = getAdapter(toolId);
36
+ if (!adapter) {
37
+ const valid = listTools()
38
+ .map((t) => t.value)
39
+ .join(', ');
40
+ throw new Error(`Unknown tool: ${toolId}. Valid tools: ${valid}.`);
41
+ }
42
+ // 2. API-ключ. В non-interactive — ТОЛЬКО из env (никогда из CLI-аргумента:
43
+ // аргумент попал бы в историю shell/процессов — это утечка секрета).
44
+ let apiKey;
45
+ if (options.nonInteractive) {
46
+ const fromEnv = process.env[API_KEY_ENV];
47
+ if (!fromEnv) {
48
+ throw new Error(`Non-interactive mode requires the ${API_KEY_ENV} environment variable (jg-...).`);
49
+ }
50
+ const valid = validateApiKey(fromEnv);
51
+ if (valid !== true) {
52
+ throw new Error(`Invalid ${API_KEY_ENV}: ${valid}`);
53
+ }
54
+ apiKey = fromEnv;
55
+ }
56
+ else {
57
+ apiKey = await deps.askApiKey();
58
+ }
59
+ // 3. Модель.
60
+ const model = resolveModel(options.model);
61
+ // 4. Применяем.
62
+ const result = await adapter.apply({ apiKey, model, scope });
63
+ return { toolId: adapter.id, result };
64
+ }
65
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AA2B/D;;;;;GAKG;AACH,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,CAAC,KAAK;QAAE,OAAO,aAAa,CAAC;IACjC,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM;QAAE,OAAO,UAAU,CAAC;IACtD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8DAA8D;AAC9D,MAAM,WAAW,GAAG,mBAAmB,CAAC;AAExC,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,OAAmB,EAAE,IAAa;IAC1D,MAAM,KAAK,GAAU,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC;IAE7C,gEAAgE;IAChE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,SAAS,EAAE;aACtB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;aACnB,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,iBAAiB,MAAM,kBAAkB,KAAK,GAAG,CAAC,CAAC;IACrE,CAAC;IAED,4EAA4E;IAC5E,wEAAwE;IACxE,IAAI,MAAc,CAAC;IACnB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,qCAAqC,WAAW,iCAAiC,CAClF,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,WAAW,WAAW,KAAK,KAAK,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,MAAM,GAAG,OAAO,CAAC;IACnB,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;IAClC,CAAC;IAED,aAAa;IACb,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAE1C,gBAAgB;IAChB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAE7D,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC;AACxC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@joingonka/setup",
3
+ "version": "0.1.0",
4
+ "description": "One-command installer that points agentic AI tools (Claude Code, OpenClaw, Cline) at JoinGonka Gateway (decentralized AI inference)",
5
+ "type": "module",
6
+ "bin": {
7
+ "joingonka-setup": "./dist/cli.js"
8
+ },
9
+ "main": "./dist/cli.js",
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "test": "vitest run",
18
+ "test:watch": "vitest",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "engines": {
22
+ "node": ">=18.0.0"
23
+ },
24
+ "dependencies": {
25
+ "commander": "^12.0.0",
26
+ "@inquirer/prompts": "^5.0.0",
27
+ "write-file-atomic": "^5.0.0"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^22.0.0",
31
+ "@types/write-file-atomic": "^4.0.0",
32
+ "typescript": "^5.0.0",
33
+ "vitest": "^2.0.0"
34
+ },
35
+ "keywords": [
36
+ "claude-code",
37
+ "openclaw",
38
+ "cline",
39
+ "anthropic",
40
+ "openai-compatible",
41
+ "ai",
42
+ "gonka",
43
+ "joingonka",
44
+ "cli",
45
+ "installer"
46
+ ],
47
+ "author": "JoinGonka <support@joingonka.ai>",
48
+ "license": "Apache-2.0",
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "https://github.com/unameisfine/joingonka-setup"
52
+ }
53
+ }