@arvoretech/hub 0.8.2 → 0.10.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.
@@ -0,0 +1,43 @@
1
+ // src/core/hub-config.ts
2
+ import { readFile } from "fs/promises";
3
+ import { existsSync } from "fs";
4
+ import { join } from "path";
5
+ import { pathToFileURL } from "url";
6
+ import { parse } from "yaml";
7
+ function resolveConfigPath(dir) {
8
+ const tsPath = join(dir, "hub.config.ts");
9
+ if (existsSync(tsPath)) return { path: tsPath, format: "typescript" };
10
+ return { path: join(dir, "hub.yaml"), format: "yaml" };
11
+ }
12
+ async function loadTypeScriptConfig(configPath) {
13
+ const fileUrl = pathToFileURL(configPath).href;
14
+ try {
15
+ const mod = await import(fileUrl);
16
+ return mod.default ?? mod;
17
+ } catch {
18
+ const { execFileSync } = await import("child_process");
19
+ const json = execFileSync("npx", ["tsx", "-e", `import c from '${configPath}'; console.log(JSON.stringify(c))`], {
20
+ encoding: "utf-8",
21
+ cwd: configPath.replace(/\/hub\.config\.ts$/, ""),
22
+ stdio: ["pipe", "pipe", "pipe"]
23
+ });
24
+ return JSON.parse(json);
25
+ }
26
+ }
27
+ async function loadHubConfig(dir) {
28
+ const { path: configPath, format } = resolveConfigPath(dir);
29
+ if (format === "typescript") {
30
+ return loadTypeScriptConfig(configPath);
31
+ }
32
+ const content = await readFile(configPath, "utf-8");
33
+ return parse(content);
34
+ }
35
+ function findHubRoot(startDir = process.cwd()) {
36
+ return startDir;
37
+ }
38
+
39
+ export {
40
+ resolveConfigPath,
41
+ loadHubConfig,
42
+ findHubRoot
43
+ };
@@ -0,0 +1,213 @@
1
+ interface Repo {
2
+ name: string;
3
+ path: string;
4
+ url: string;
5
+ tech?: string;
6
+ description?: string;
7
+ display_name?: string;
8
+ env_file?: string;
9
+ commands?: {
10
+ install?: string;
11
+ dev?: string;
12
+ build?: string;
13
+ lint?: string;
14
+ test?: string;
15
+ [key: string]: string | undefined;
16
+ };
17
+ skills?: string[];
18
+ tools?: Record<string, string>;
19
+ }
20
+ interface Service {
21
+ name: string;
22
+ image: string;
23
+ port?: number;
24
+ ports?: number[];
25
+ env?: Record<string, string>;
26
+ }
27
+ interface MCPConfig {
28
+ name: string;
29
+ description?: string;
30
+ instructions?: string;
31
+ package?: string;
32
+ url?: string;
33
+ image?: string;
34
+ env?: Record<string, string>;
35
+ upstreams?: string[];
36
+ autoApprove?: boolean | string[];
37
+ }
38
+ interface IntegrationConfig {
39
+ linear?: {
40
+ team?: string;
41
+ labels?: string[];
42
+ link_pattern?: string;
43
+ };
44
+ github?: {
45
+ org?: string;
46
+ pr_branch_pattern?: string;
47
+ pr_tool?: "cli" | "mcp";
48
+ };
49
+ slack?: {
50
+ channels?: Record<string, string>;
51
+ templates?: Record<string, string>;
52
+ };
53
+ playwright?: {
54
+ base_url?: string;
55
+ };
56
+ }
57
+ interface WorkflowStep {
58
+ step: string;
59
+ agent?: string;
60
+ agents?: (string | {
61
+ agent: string;
62
+ when?: string;
63
+ output?: string;
64
+ })[];
65
+ parallel?: boolean;
66
+ output?: string;
67
+ tools?: string[];
68
+ when?: string;
69
+ actions?: string[];
70
+ mode?: "plan" | "agent";
71
+ }
72
+ interface SecretRef {
73
+ secret: string;
74
+ profile?: string;
75
+ }
76
+ interface BuildDatabaseUrl {
77
+ from_secret: string;
78
+ profile?: string;
79
+ vars?: {
80
+ user?: string;
81
+ password?: string;
82
+ host?: string;
83
+ port?: string;
84
+ database?: string;
85
+ };
86
+ template?: string;
87
+ }
88
+ interface EnvProfile {
89
+ description?: string;
90
+ services?: string[];
91
+ aws_profile?: string;
92
+ secrets?: Record<string, string | SecretRef>;
93
+ build_database_url?: Record<string, BuildDatabaseUrl>;
94
+ }
95
+ interface MiseSettings {
96
+ experimental?: boolean;
97
+ [key: string]: unknown;
98
+ }
99
+ interface PromptCustomization {
100
+ prepend?: string;
101
+ append?: string;
102
+ sections?: Record<string, string>;
103
+ }
104
+ interface HookEntry {
105
+ type: "command" | "prompt";
106
+ command?: string;
107
+ prompt?: string;
108
+ matcher?: string;
109
+ timeout_ms?: number;
110
+ }
111
+ interface MemoryConfig {
112
+ path?: string;
113
+ categories?: string[];
114
+ auto_capture?: boolean;
115
+ embedding_model?: string;
116
+ }
117
+ interface RemoteSource {
118
+ name: string;
119
+ type: "skill" | "steering";
120
+ notion_page?: string;
121
+ url?: string;
122
+ path?: string;
123
+ instructions?: string;
124
+ triggers?: string[];
125
+ }
126
+ interface DesignLibrary {
127
+ name: string;
128
+ mcp?: string;
129
+ url?: string;
130
+ path?: string;
131
+ }
132
+ interface DesignConfig {
133
+ skills?: string[];
134
+ libraries?: DesignLibrary[];
135
+ icons?: string;
136
+ instructions?: string;
137
+ }
138
+ interface HubConfig {
139
+ name: string;
140
+ description?: string;
141
+ version?: string;
142
+ tools?: Record<string, string>;
143
+ mise_settings?: MiseSettings;
144
+ repos: Repo[];
145
+ services?: Service[];
146
+ env?: {
147
+ profiles?: Record<string, EnvProfile>;
148
+ overrides?: Record<string, Record<string, Record<string, string>>>;
149
+ };
150
+ mcps?: MCPConfig[];
151
+ integrations?: IntegrationConfig;
152
+ hooks?: Record<string, HookEntry[]>;
153
+ commands?: Record<string, string>;
154
+ commands_dir?: string;
155
+ memory?: MemoryConfig;
156
+ remote_sources?: RemoteSource[];
157
+ design?: DesignConfig;
158
+ workflow?: {
159
+ task_folder?: string;
160
+ pipeline?: WorkflowStep[];
161
+ prompt?: PromptCustomization;
162
+ enforce_workflow?: boolean;
163
+ };
164
+ }
165
+
166
+ declare function defineConfig(config: HubConfig): HubConfig;
167
+ type RepoOverrides = Partial<Omit<Repo, "name" | "path" | "url" | "tech">>;
168
+ declare const repo: {
169
+ nestjs: (name: string, url: string, overrides?: RepoOverrides) => Repo;
170
+ nextjs: (name: string, url: string, overrides?: RepoOverrides) => Repo;
171
+ react: (name: string, url: string, overrides?: RepoOverrides) => Repo;
172
+ elixir: (name: string, url: string, overrides?: RepoOverrides) => Repo;
173
+ go: (name: string, url: string, overrides?: RepoOverrides) => Repo;
174
+ python: (name: string, url: string, overrides?: RepoOverrides) => Repo;
175
+ custom(name: string, url: string, config?: RepoOverrides & {
176
+ tech?: string;
177
+ }): Repo;
178
+ };
179
+ type MCPOverrides = Partial<Omit<MCPConfig, "name">>;
180
+ declare const mcp: {
181
+ postgresql(name: string, overrides?: MCPOverrides): MCPConfig;
182
+ mysql(name: string, overrides?: MCPOverrides): MCPConfig;
183
+ clickhouse(name: string, overrides?: MCPOverrides): MCPConfig;
184
+ datadog(overrides?: MCPOverrides): MCPConfig;
185
+ memory(overrides?: MCPOverrides): MCPConfig;
186
+ sendgrid(overrides?: MCPOverrides): MCPConfig;
187
+ launchdarkly(overrides?: MCPOverrides): MCPConfig;
188
+ tempmail(overrides?: MCPOverrides): MCPConfig;
189
+ awsSecretsManager(overrides?: MCPOverrides): MCPConfig;
190
+ npmRegistry(overrides?: MCPOverrides): MCPConfig;
191
+ runtimeLens(overrides?: MCPOverrides): MCPConfig;
192
+ meetTranscriptions(overrides?: MCPOverrides): MCPConfig;
193
+ googleChat(overrides?: MCPOverrides): MCPConfig;
194
+ playwright(overrides?: MCPOverrides): MCPConfig;
195
+ context7(overrides?: MCPOverrides): MCPConfig;
196
+ proxy(name: string, overrides: MCPOverrides & {
197
+ upstreams: string[];
198
+ }): MCPConfig;
199
+ custom(name: string, overrides?: MCPOverrides): MCPConfig;
200
+ };
201
+ type ServiceOverrides = Partial<Omit<Service, "name" | "image">>;
202
+ declare const service: {
203
+ mysql: (name: string, overrides?: ServiceOverrides) => Service;
204
+ postgres: (name: string, overrides?: ServiceOverrides) => Service;
205
+ redis: (name: string, overrides?: ServiceOverrides) => Service;
206
+ mongo: (name: string, overrides?: ServiceOverrides) => Service;
207
+ rabbitmq: (name: string, overrides?: ServiceOverrides) => Service;
208
+ elasticsearch: (name: string, overrides?: ServiceOverrides) => Service;
209
+ clickhouse: (name: string, overrides?: ServiceOverrides) => Service;
210
+ custom(name: string, image: string, overrides?: ServiceOverrides): Service;
211
+ };
212
+
213
+ export { type DesignConfig, type EnvProfile, type HookEntry, type HubConfig, type IntegrationConfig, type MCPConfig, type MemoryConfig, type Repo, type Service, type WorkflowStep, defineConfig, mcp, repo, service };
@@ -0,0 +1,234 @@
1
+ // src/config/define-config.ts
2
+ function defineConfig(config) {
3
+ return config;
4
+ }
5
+ function createRepo(tech, defaults) {
6
+ return (name, url, overrides) => {
7
+ const merged = { ...defaults, ...overrides?.commands };
8
+ const rest = Object.fromEntries(
9
+ Object.entries(overrides ?? {}).filter(([key]) => key !== "commands")
10
+ );
11
+ return {
12
+ name,
13
+ path: `./${name}`,
14
+ url,
15
+ tech,
16
+ commands: merged,
17
+ ...rest
18
+ };
19
+ };
20
+ }
21
+ var repo = {
22
+ nestjs: createRepo("nestjs", {
23
+ install: "pnpm install",
24
+ dev: "pnpm dev",
25
+ build: "pnpm build",
26
+ test: "pnpm test",
27
+ lint: "pnpm lint"
28
+ }),
29
+ nextjs: createRepo("nextjs", {
30
+ install: "pnpm install",
31
+ dev: "pnpm dev",
32
+ build: "pnpm build",
33
+ test: "pnpm test",
34
+ lint: "pnpm lint"
35
+ }),
36
+ react: createRepo("react", {
37
+ install: "pnpm install",
38
+ dev: "pnpm dev",
39
+ build: "pnpm build",
40
+ test: "pnpm test",
41
+ lint: "pnpm lint"
42
+ }),
43
+ elixir: createRepo("elixir", {
44
+ install: "mix deps.get",
45
+ dev: "mix phx.server",
46
+ test: "mix test",
47
+ lint: "mix credo"
48
+ }),
49
+ go: createRepo("go", {
50
+ install: "go mod download",
51
+ build: "go build ./...",
52
+ test: "go test ./...",
53
+ lint: "golangci-lint run"
54
+ }),
55
+ python: createRepo("python", {
56
+ install: "pip install -r requirements.txt",
57
+ dev: "python manage.py runserver",
58
+ test: "pytest",
59
+ lint: "ruff check ."
60
+ }),
61
+ custom(name, url, config) {
62
+ const { tech, ...rest } = config ?? {};
63
+ return {
64
+ name,
65
+ path: `./${name}`,
66
+ url,
67
+ ...tech && { tech },
68
+ ...rest
69
+ };
70
+ }
71
+ };
72
+ var mcp = {
73
+ postgresql(name, overrides) {
74
+ return {
75
+ name,
76
+ package: "@arvoretech/postgresql-mcp",
77
+ ...overrides,
78
+ env: { ...overrides?.env }
79
+ };
80
+ },
81
+ mysql(name, overrides) {
82
+ return {
83
+ name,
84
+ package: "@arvoretech/mysql-mcp",
85
+ ...overrides,
86
+ env: { ...overrides?.env }
87
+ };
88
+ },
89
+ clickhouse(name, overrides) {
90
+ return {
91
+ name,
92
+ package: "@arvoretech/clickhouse-mcp",
93
+ ...overrides,
94
+ env: { ...overrides?.env }
95
+ };
96
+ },
97
+ datadog(overrides) {
98
+ return {
99
+ name: "datadog",
100
+ package: "@arvoretech/datadog-mcp",
101
+ ...overrides,
102
+ env: { ...overrides?.env }
103
+ };
104
+ },
105
+ memory(overrides) {
106
+ return {
107
+ name: "team-memory",
108
+ package: "@arvoretech/memory-mcp",
109
+ ...overrides,
110
+ env: { ...overrides?.env }
111
+ };
112
+ },
113
+ sendgrid(overrides) {
114
+ return {
115
+ name: "sendgrid",
116
+ package: "@arvoretech/sendgrid-mcp",
117
+ ...overrides,
118
+ env: { ...overrides?.env }
119
+ };
120
+ },
121
+ launchdarkly(overrides) {
122
+ return {
123
+ name: "launchdarkly",
124
+ package: "@arvoretech/launchdarkly-mcp",
125
+ ...overrides,
126
+ env: { ...overrides?.env }
127
+ };
128
+ },
129
+ tempmail(overrides) {
130
+ return {
131
+ name: "tempmail",
132
+ package: "@arvoretech/tempmail-mcp",
133
+ ...overrides,
134
+ env: { ...overrides?.env }
135
+ };
136
+ },
137
+ awsSecretsManager(overrides) {
138
+ return {
139
+ name: "aws-secrets-manager",
140
+ package: "@arvoretech/aws-secrets-manager-mcp",
141
+ ...overrides,
142
+ env: { ...overrides?.env }
143
+ };
144
+ },
145
+ npmRegistry(overrides) {
146
+ return {
147
+ name: "npm-registry",
148
+ package: "@arvoretech/npm-registry-mcp",
149
+ ...overrides
150
+ };
151
+ },
152
+ runtimeLens(overrides) {
153
+ return {
154
+ name: "runtime-lens",
155
+ package: "runtime-lens",
156
+ ...overrides,
157
+ env: { ...overrides?.env }
158
+ };
159
+ },
160
+ meetTranscriptions(overrides) {
161
+ return {
162
+ name: "meet-transcriptions",
163
+ package: "@arvoretech/meet-transcriptions-mcp",
164
+ ...overrides,
165
+ env: { ...overrides?.env }
166
+ };
167
+ },
168
+ googleChat(overrides) {
169
+ return {
170
+ name: "google-chat",
171
+ package: "@arvoretech/google-chat-mcp",
172
+ ...overrides,
173
+ env: { ...overrides?.env }
174
+ };
175
+ },
176
+ playwright(overrides) {
177
+ return {
178
+ name: "playwright",
179
+ package: "@playwright/mcp",
180
+ ...overrides
181
+ };
182
+ },
183
+ context7(overrides) {
184
+ return {
185
+ name: "context7",
186
+ package: "@upstash/context7-mcp",
187
+ ...overrides
188
+ };
189
+ },
190
+ proxy(name, overrides) {
191
+ return {
192
+ name,
193
+ package: "@arvoretech/mcp-proxy",
194
+ ...overrides,
195
+ env: { ...overrides?.env }
196
+ };
197
+ },
198
+ custom(name, overrides) {
199
+ return {
200
+ name,
201
+ ...overrides
202
+ };
203
+ }
204
+ };
205
+ function createService(image, defaultPort) {
206
+ return (name, overrides) => ({
207
+ name,
208
+ image,
209
+ port: overrides?.port ?? defaultPort,
210
+ ...overrides
211
+ });
212
+ }
213
+ var service = {
214
+ mysql: createService("mysql:8", 3306),
215
+ postgres: createService("postgres:16", 5432),
216
+ redis: createService("redis:7", 6379),
217
+ mongo: createService("mongo:7", 27017),
218
+ rabbitmq: createService("rabbitmq:3-management", 5672),
219
+ elasticsearch: createService("elasticsearch:8.12.0", 9200),
220
+ clickhouse: createService("clickhouse/clickhouse-server:24", 8123),
221
+ custom(name, image, overrides) {
222
+ return {
223
+ name,
224
+ image,
225
+ ...overrides
226
+ };
227
+ }
228
+ };
229
+ export {
230
+ defineConfig,
231
+ mcp,
232
+ repo,
233
+ service
234
+ };
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  generateCommand,
3
3
  generators
4
- } from "./chunk-T2UKYK2B.js";
4
+ } from "./chunk-MDJG7IOU.js";
5
+ import "./chunk-VMN4KGAK.js";
5
6
  export {
6
7
  generateCommand,
7
8
  generators
@@ -0,0 +1,10 @@
1
+ import {
2
+ findHubRoot,
3
+ loadHubConfig,
4
+ resolveConfigPath
5
+ } from "./chunk-VMN4KGAK.js";
6
+ export {
7
+ findHubRoot,
8
+ loadHubConfig,
9
+ resolveConfigPath
10
+ };