@arvoretech/hub 0.9.0 → 0.11.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,214 @@
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
+ reactNative: (name: string, url: string, overrides?: RepoOverrides) => Repo;
173
+ elixir: (name: string, url: string, overrides?: RepoOverrides) => Repo;
174
+ go: (name: string, url: string, overrides?: RepoOverrides) => Repo;
175
+ python: (name: string, url: string, overrides?: RepoOverrides) => Repo;
176
+ custom(name: string, url: string, config?: RepoOverrides & {
177
+ tech?: string;
178
+ }): Repo;
179
+ };
180
+ type MCPOverrides = Partial<Omit<MCPConfig, "name">>;
181
+ declare const mcp: {
182
+ postgresql(name: string, overrides?: MCPOverrides): MCPConfig;
183
+ mysql(name: string, overrides?: MCPOverrides): MCPConfig;
184
+ clickhouse(name: string, overrides?: MCPOverrides): MCPConfig;
185
+ datadog(overrides?: MCPOverrides): MCPConfig;
186
+ memory(overrides?: MCPOverrides): MCPConfig;
187
+ sendgrid(overrides?: MCPOverrides): MCPConfig;
188
+ launchdarkly(overrides?: MCPOverrides): MCPConfig;
189
+ tempmail(overrides?: MCPOverrides): MCPConfig;
190
+ awsSecretsManager(overrides?: MCPOverrides): MCPConfig;
191
+ npmRegistry(overrides?: MCPOverrides): MCPConfig;
192
+ runtimeLens(overrides?: MCPOverrides): MCPConfig;
193
+ meetTranscriptions(overrides?: MCPOverrides): MCPConfig;
194
+ googleChat(overrides?: MCPOverrides): MCPConfig;
195
+ playwright(overrides?: MCPOverrides): MCPConfig;
196
+ context7(overrides?: MCPOverrides): MCPConfig;
197
+ proxy(name: string, overrides: MCPOverrides & {
198
+ upstreams: string[];
199
+ }): MCPConfig;
200
+ custom(name: string, overrides?: MCPOverrides): MCPConfig;
201
+ };
202
+ type ServiceOverrides = Partial<Omit<Service, "name" | "image">>;
203
+ declare const service: {
204
+ mysql: (name: string, overrides?: ServiceOverrides) => Service;
205
+ postgres: (name: string, overrides?: ServiceOverrides) => Service;
206
+ redis: (name: string, overrides?: ServiceOverrides) => Service;
207
+ mongo: (name: string, overrides?: ServiceOverrides) => Service;
208
+ rabbitmq: (name: string, overrides?: ServiceOverrides) => Service;
209
+ elasticsearch: (name: string, overrides?: ServiceOverrides) => Service;
210
+ clickhouse: (name: string, overrides?: ServiceOverrides) => Service;
211
+ custom(name: string, image: string, overrides?: ServiceOverrides): Service;
212
+ };
213
+
214
+ 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,241 @@
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
+ reactNative: createRepo("react-native", {
44
+ install: "pnpm install",
45
+ dev: "pnpm start",
46
+ build: "pnpm build",
47
+ test: "pnpm test",
48
+ lint: "pnpm lint"
49
+ }),
50
+ elixir: createRepo("elixir", {
51
+ install: "mix deps.get",
52
+ dev: "mix phx.server",
53
+ test: "mix test",
54
+ lint: "mix credo"
55
+ }),
56
+ go: createRepo("go", {
57
+ install: "go mod download",
58
+ build: "go build ./...",
59
+ test: "go test ./...",
60
+ lint: "golangci-lint run"
61
+ }),
62
+ python: createRepo("python", {
63
+ install: "pip install -r requirements.txt",
64
+ dev: "python manage.py runserver",
65
+ test: "pytest",
66
+ lint: "ruff check ."
67
+ }),
68
+ custom(name, url, config) {
69
+ const { tech, ...rest } = config ?? {};
70
+ return {
71
+ name,
72
+ path: `./${name}`,
73
+ url,
74
+ ...tech && { tech },
75
+ ...rest
76
+ };
77
+ }
78
+ };
79
+ var mcp = {
80
+ postgresql(name, overrides) {
81
+ return {
82
+ name,
83
+ package: "@arvoretech/postgresql-mcp",
84
+ ...overrides,
85
+ env: { ...overrides?.env }
86
+ };
87
+ },
88
+ mysql(name, overrides) {
89
+ return {
90
+ name,
91
+ package: "@arvoretech/mysql-mcp",
92
+ ...overrides,
93
+ env: { ...overrides?.env }
94
+ };
95
+ },
96
+ clickhouse(name, overrides) {
97
+ return {
98
+ name,
99
+ package: "@arvoretech/clickhouse-mcp",
100
+ ...overrides,
101
+ env: { ...overrides?.env }
102
+ };
103
+ },
104
+ datadog(overrides) {
105
+ return {
106
+ name: "datadog",
107
+ package: "@arvoretech/datadog-mcp",
108
+ ...overrides,
109
+ env: { ...overrides?.env }
110
+ };
111
+ },
112
+ memory(overrides) {
113
+ return {
114
+ name: "team-memory",
115
+ package: "@arvoretech/memory-mcp",
116
+ ...overrides,
117
+ env: { ...overrides?.env }
118
+ };
119
+ },
120
+ sendgrid(overrides) {
121
+ return {
122
+ name: "sendgrid",
123
+ package: "@arvoretech/sendgrid-mcp",
124
+ ...overrides,
125
+ env: { ...overrides?.env }
126
+ };
127
+ },
128
+ launchdarkly(overrides) {
129
+ return {
130
+ name: "launchdarkly",
131
+ package: "@arvoretech/launchdarkly-mcp",
132
+ ...overrides,
133
+ env: { ...overrides?.env }
134
+ };
135
+ },
136
+ tempmail(overrides) {
137
+ return {
138
+ name: "tempmail",
139
+ package: "@arvoretech/tempmail-mcp",
140
+ ...overrides,
141
+ env: { ...overrides?.env }
142
+ };
143
+ },
144
+ awsSecretsManager(overrides) {
145
+ return {
146
+ name: "aws-secrets-manager",
147
+ package: "@arvoretech/aws-secrets-manager-mcp",
148
+ ...overrides,
149
+ env: { ...overrides?.env }
150
+ };
151
+ },
152
+ npmRegistry(overrides) {
153
+ return {
154
+ name: "npm-registry",
155
+ package: "@arvoretech/npm-registry-mcp",
156
+ ...overrides
157
+ };
158
+ },
159
+ runtimeLens(overrides) {
160
+ return {
161
+ name: "runtime-lens",
162
+ package: "runtime-lens",
163
+ ...overrides,
164
+ env: { ...overrides?.env }
165
+ };
166
+ },
167
+ meetTranscriptions(overrides) {
168
+ return {
169
+ name: "meet-transcriptions",
170
+ package: "@arvoretech/meet-transcriptions-mcp",
171
+ ...overrides,
172
+ env: { ...overrides?.env }
173
+ };
174
+ },
175
+ googleChat(overrides) {
176
+ return {
177
+ name: "google-chat",
178
+ package: "@arvoretech/google-chat-mcp",
179
+ ...overrides,
180
+ env: { ...overrides?.env }
181
+ };
182
+ },
183
+ playwright(overrides) {
184
+ return {
185
+ name: "playwright",
186
+ package: "@playwright/mcp",
187
+ ...overrides
188
+ };
189
+ },
190
+ context7(overrides) {
191
+ return {
192
+ name: "context7",
193
+ package: "@upstash/context7-mcp",
194
+ ...overrides
195
+ };
196
+ },
197
+ proxy(name, overrides) {
198
+ return {
199
+ name,
200
+ package: "@arvoretech/mcp-proxy",
201
+ ...overrides,
202
+ env: { ...overrides?.env }
203
+ };
204
+ },
205
+ custom(name, overrides) {
206
+ return {
207
+ name,
208
+ ...overrides
209
+ };
210
+ }
211
+ };
212
+ function createService(image, defaultPort) {
213
+ return (name, overrides) => ({
214
+ name,
215
+ image,
216
+ port: overrides?.port ?? defaultPort,
217
+ ...overrides
218
+ });
219
+ }
220
+ var service = {
221
+ mysql: createService("mysql:8", 3306),
222
+ postgres: createService("postgres:16", 5432),
223
+ redis: createService("redis:7", 6379),
224
+ mongo: createService("mongo:7", 27017),
225
+ rabbitmq: createService("rabbitmq:3-management", 5672),
226
+ elasticsearch: createService("elasticsearch:8.12.0", 9200),
227
+ clickhouse: createService("clickhouse/clickhouse-server:24", 8123),
228
+ custom(name, image, overrides) {
229
+ return {
230
+ name,
231
+ image,
232
+ ...overrides
233
+ };
234
+ }
235
+ };
236
+ export {
237
+ defineConfig,
238
+ mcp,
239
+ repo,
240
+ service
241
+ };
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  generateCommand,
3
3
  generators
4
- } from "./chunk-NUJMJOEK.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
+ };