@generacy-ai/config 0.1.1 → 0.3.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,27 @@
1
+ import { z } from 'zod';
2
+ export declare const ClusterYamlSchema: z.ZodObject<{
3
+ channel: z.ZodOptional<z.ZodEnum<["preview", "stable"]>>;
4
+ workers: z.ZodOptional<z.ZodNumber>;
5
+ variant: z.ZodOptional<z.ZodEnum<["cluster-base", "cluster-microservices"]>>;
6
+ appConfig: z.ZodOptional<z.ZodUnknown>;
7
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
8
+ channel: z.ZodOptional<z.ZodEnum<["preview", "stable"]>>;
9
+ workers: z.ZodOptional<z.ZodNumber>;
10
+ variant: z.ZodOptional<z.ZodEnum<["cluster-base", "cluster-microservices"]>>;
11
+ appConfig: z.ZodOptional<z.ZodUnknown>;
12
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
13
+ channel: z.ZodOptional<z.ZodEnum<["preview", "stable"]>>;
14
+ workers: z.ZodOptional<z.ZodNumber>;
15
+ variant: z.ZodOptional<z.ZodEnum<["cluster-base", "cluster-microservices"]>>;
16
+ appConfig: z.ZodOptional<z.ZodUnknown>;
17
+ }, z.ZodTypeAny, "passthrough">>;
18
+ export type ClusterYamlData = z.infer<typeof ClusterYamlSchema>;
19
+ export declare const ClusterLocalYamlSchema: z.ZodObject<{
20
+ workers: z.ZodOptional<z.ZodNumber>;
21
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
22
+ workers: z.ZodOptional<z.ZodNumber>;
23
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
24
+ workers: z.ZodOptional<z.ZodNumber>;
25
+ }, z.ZodTypeAny, "passthrough">>;
26
+ export type ClusterLocalYamlData = z.infer<typeof ClusterLocalYamlSchema>;
27
+ //# sourceMappingURL=cluster-config-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cluster-config-schema.d.ts","sourceRoot":"","sources":["../src/cluster-config-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;gCAOd,CAAC;AAEjB,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEhE,eAAO,MAAM,sBAAsB;;;;;;gCAInB,CAAC;AAEjB,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { z } from 'zod';
2
+ export const ClusterYamlSchema = z
3
+ .object({
4
+ channel: z.enum(['preview', 'stable']).optional(),
5
+ workers: z.number().int().min(1).optional(),
6
+ variant: z.enum(['cluster-base', 'cluster-microservices']).optional(),
7
+ appConfig: z.unknown().optional(),
8
+ })
9
+ .passthrough();
10
+ export const ClusterLocalYamlSchema = z
11
+ .object({
12
+ workers: z.number().int().min(1).optional(),
13
+ })
14
+ .passthrough();
15
+ //# sourceMappingURL=cluster-config-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cluster-config-schema.js","sourceRoot":"","sources":["../src/cluster-config-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC;KAC/B,MAAM,CAAC;IACN,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE;IACjD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC3C,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,uBAAuB,CAAC,CAAC,CAAC,QAAQ,EAAE;IACrE,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CAClC,CAAC;KACD,WAAW,EAAE,CAAC;AAIjB,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC;KACpC,MAAM,CAAC;IACN,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC5C,CAAC;KACD,WAAW,EAAE,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { type ClusterLocalYamlData, type ClusterYamlData } from './cluster-config-schema.js';
2
+ export interface MergedClusterConfig {
3
+ /** Shallow per-top-level-key merge: cluster.local.yaml wins per key. */
4
+ merged: ClusterYamlData;
5
+ /** Raw parsed `cluster.yaml`, or `{}` if missing. */
6
+ canonical: ClusterYamlData;
7
+ /** Raw parsed `cluster.local.yaml`, or `{}` if missing. */
8
+ local: ClusterLocalYamlData;
9
+ }
10
+ /**
11
+ * Read .generacy/cluster.yaml and .generacy/cluster.local.yaml, returning the
12
+ * shallow-merged view (local wins per top-level key) plus each raw form.
13
+ *
14
+ * - ENOENT on either file → empty object.
15
+ * - Malformed YAML on either file → throw (fail loud).
16
+ * - Both files missing → all three returned fields are {}.
17
+ */
18
+ export declare function readMergedClusterConfig(generacyDir: string): Promise<MergedClusterConfig>;
19
+ //# sourceMappingURL=cluster-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cluster-config.d.ts","sourceRoot":"","sources":["../src/cluster-config.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACrB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,WAAW,mBAAmB;IAClC,wEAAwE;IACxE,MAAM,EAAE,eAAe,CAAC;IACxB,qDAAqD;IACrD,SAAS,EAAE,eAAe,CAAC;IAC3B,2DAA2D;IAC3D,KAAK,EAAE,oBAAoB,CAAC;CAC7B;AAiCD;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAe9B"}
@@ -0,0 +1,51 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { parse as parseYaml } from 'yaml';
4
+ import { ClusterLocalYamlSchema, ClusterYamlSchema, } from './cluster-config-schema.js';
5
+ async function readAndParse(filePath, schema) {
6
+ let raw;
7
+ try {
8
+ raw = await readFile(filePath, 'utf-8');
9
+ }
10
+ catch (err) {
11
+ if (err.code === 'ENOENT')
12
+ return null;
13
+ throw err;
14
+ }
15
+ let parsed;
16
+ try {
17
+ parsed = parseYaml(raw);
18
+ }
19
+ catch (err) {
20
+ const message = err instanceof Error ? err.message : String(err);
21
+ throw new Error(`Failed to parse YAML at ${filePath}: ${message}`);
22
+ }
23
+ if (parsed == null) {
24
+ return schema.parse({});
25
+ }
26
+ if (typeof parsed !== 'object') {
27
+ throw new Error(`Expected YAML object at ${filePath}, got ${typeof parsed}`);
28
+ }
29
+ return schema.parse(parsed);
30
+ }
31
+ /**
32
+ * Read .generacy/cluster.yaml and .generacy/cluster.local.yaml, returning the
33
+ * shallow-merged view (local wins per top-level key) plus each raw form.
34
+ *
35
+ * - ENOENT on either file → empty object.
36
+ * - Malformed YAML on either file → throw (fail loud).
37
+ * - Both files missing → all three returned fields are {}.
38
+ */
39
+ export async function readMergedClusterConfig(generacyDir) {
40
+ const canonicalPath = join(generacyDir, 'cluster.yaml');
41
+ const localPath = join(generacyDir, 'cluster.local.yaml');
42
+ const [canonicalParsed, localParsed] = await Promise.all([
43
+ readAndParse(canonicalPath, ClusterYamlSchema),
44
+ readAndParse(localPath, ClusterLocalYamlSchema),
45
+ ]);
46
+ const canonical = canonicalParsed ?? {};
47
+ const local = localParsed ?? {};
48
+ const merged = { ...canonical, ...local };
49
+ return { merged, canonical, local };
50
+ }
51
+ //# sourceMappingURL=cluster-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cluster-config.js","sourceRoot":"","sources":["../src/cluster-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EACL,sBAAsB,EACtB,iBAAiB,GAGlB,MAAM,4BAA4B,CAAC;AAWpC,KAAK,UAAU,YAAY,CACzB,QAAgB,EAChB,MAAoC;IAEpC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAClE,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,2BAA2B,QAAQ,KAAK,OAAO,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,2BAA2B,QAAQ,SAAS,OAAO,MAAM,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,WAAmB;IAEnB,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;IAE1D,MAAM,CAAC,eAAe,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACvD,YAAY,CAAC,aAAa,EAAE,iBAAiB,CAAC;QAC9C,YAAY,CAAC,SAAS,EAAE,sBAAsB,CAAC;KAChD,CAAC,CAAC;IAEH,MAAM,SAAS,GAAoB,eAAe,IAAI,EAAE,CAAC;IACzD,MAAM,KAAK,GAAyB,WAAW,IAAI,EAAE,CAAC;IAEtD,MAAM,MAAM,GAAoB,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,EAAE,CAAC;IAE3D,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AACtC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  export { WorkspaceRepoSchema, WorkspaceConfigSchema, type WorkspaceRepo, type WorkspaceConfig, } from './workspace-schema.js';
2
- export { getWorkspaceRepos, getMonitoredRepos, getRepoNames, getRepoWorkdir, } from './repos.js';
2
+ export { getWorkspaceRepos, getMonitoredRepos, getRepoNames, getRepoWorkdir, resolveSiblingWorkdirs, } from './repos.js';
3
3
  export { parseRepoInput, parseRepoList } from './parse-repo-input.js';
4
4
  export { detectRepoDrift } from './drift.js';
5
5
  export { TemplateReposSchema, TemplateConfigSchema, OrchestratorSettingsSchema, type TemplateConfig, type OrchestratorSettings, } from './template-schema.js';
6
6
  export { convertTemplateConfig } from './convert-template.js';
7
7
  export { tryLoadWorkspaceConfig, tryLoadOrchestratorSettings, tryLoadDefaultsRole, findWorkspaceConfigPath, scanForWorkspaceConfig } from './loader.js';
8
+ export { ClusterYamlSchema, ClusterLocalYamlSchema, type ClusterYamlData, type ClusterLocalYamlData, } from './cluster-config-schema.js';
9
+ export { readMergedClusterConfig, type MergedClusterConfig } from './cluster-config.js';
8
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,KAAK,cAAc,EACnB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,KAAK,cAAc,EACnB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAExJ,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,KAAK,eAAe,EACpB,KAAK,oBAAoB,GAC1B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,uBAAuB,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  // @generacy-ai/config - Centralized workspace configuration
2
2
  export { WorkspaceRepoSchema, WorkspaceConfigSchema, } from './workspace-schema.js';
3
- export { getWorkspaceRepos, getMonitoredRepos, getRepoNames, getRepoWorkdir, } from './repos.js';
3
+ export { getWorkspaceRepos, getMonitoredRepos, getRepoNames, getRepoWorkdir, resolveSiblingWorkdirs, } from './repos.js';
4
4
  export { parseRepoInput, parseRepoList } from './parse-repo-input.js';
5
5
  export { detectRepoDrift } from './drift.js';
6
6
  export { TemplateReposSchema, TemplateConfigSchema, OrchestratorSettingsSchema, } from './template-schema.js';
7
7
  export { convertTemplateConfig } from './convert-template.js';
8
8
  export { tryLoadWorkspaceConfig, tryLoadOrchestratorSettings, tryLoadDefaultsRole, findWorkspaceConfigPath, scanForWorkspaceConfig } from './loader.js';
9
+ export { ClusterYamlSchema, ClusterLocalYamlSchema, } from './cluster-config-schema.js';
10
+ export { readMergedClusterConfig } from './cluster-config.js';
9
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAE5D,OAAO,EACL,mBAAmB,EACnB,qBAAqB,GAGtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,GAG3B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAE5D,OAAO,EACL,mBAAmB,EACnB,qBAAqB,GAGtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,GAG3B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAExJ,OAAO,EACL,iBAAiB,EACjB,sBAAsB,GAGvB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,uBAAuB,EAA4B,MAAM,qBAAqB,CAAC"}
package/dist/repos.d.ts CHANGED
@@ -21,4 +21,14 @@ export declare function getRepoNames(config: WorkspaceConfig): string[];
21
21
  * Returns the local working directory path for a repo.
22
22
  */
23
23
  export declare function getRepoWorkdir(repoName: string, basePath?: string): string;
24
+ /**
25
+ * Resolves sibling working directories from workspace config.
26
+ * Returns a map of repo name → absolute path for all repos
27
+ * except the primary (identified by matching against primaryWorkdir).
28
+ *
29
+ * Returns empty map if:
30
+ * - No repo path matches primaryWorkdir (fail closed)
31
+ * - All sibling paths don't exist on disk
32
+ */
33
+ export declare function resolveSiblingWorkdirs(config: WorkspaceConfig, primaryWorkdir: string, basePath?: string): Record<string, string>;
24
34
  //# sourceMappingURL=repos.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"repos.d.ts","sourceRoot":"","sources":["../src/repos.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,eAAe,GACtB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAEnC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,eAAe,GACtB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAInC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,EAAE,CAE9D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,MAAsB,GAC/B,MAAM,CAER"}
1
+ {"version":3,"file":"repos.d.ts","sourceRoot":"","sources":["../src/repos.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,eAAe,GACtB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAEnC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,eAAe,GACtB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAInC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,EAAE,CAE9D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,MAAsB,GAC/B,MAAM,CAER;AAcD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,eAAe,EACvB,cAAc,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA4BxB"}
package/dist/repos.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { existsSync, realpathSync } from 'node:fs';
2
+ import { dirname, resolve } from 'node:path';
1
3
  /**
2
4
  * Returns all repos from the workspace config with owner/repo info.
3
5
  */
@@ -24,4 +26,47 @@ export function getRepoNames(config) {
24
26
  export function getRepoWorkdir(repoName, basePath = '/workspaces') {
25
27
  return `${basePath}/${repoName}`;
26
28
  }
29
+ /**
30
+ * Normalize a path via realpathSync (resolves symlinks).
31
+ * Falls back to path.resolve() if the path doesn't exist or realpathSync throws.
32
+ */
33
+ function normalizePath(p) {
34
+ try {
35
+ return realpathSync.native(p);
36
+ }
37
+ catch {
38
+ return resolve(p);
39
+ }
40
+ }
41
+ /**
42
+ * Resolves sibling working directories from workspace config.
43
+ * Returns a map of repo name → absolute path for all repos
44
+ * except the primary (identified by matching against primaryWorkdir).
45
+ *
46
+ * Returns empty map if:
47
+ * - No repo path matches primaryWorkdir (fail closed)
48
+ * - All sibling paths don't exist on disk
49
+ */
50
+ export function resolveSiblingWorkdirs(config, primaryWorkdir, basePath) {
51
+ const resolvedBase = basePath ?? dirname(resolve(primaryWorkdir));
52
+ const normalizedPrimary = normalizePath(primaryWorkdir);
53
+ const result = {};
54
+ let foundPrimary = false;
55
+ for (const repo of config.repos) {
56
+ const candidatePath = getRepoWorkdir(repo.name, resolvedBase);
57
+ const normalizedCandidate = normalizePath(candidatePath);
58
+ if (normalizedCandidate === normalizedPrimary) {
59
+ foundPrimary = true;
60
+ continue;
61
+ }
62
+ if (!existsSync(candidatePath)) {
63
+ continue;
64
+ }
65
+ result[repo.name] = normalizedCandidate;
66
+ }
67
+ if (!foundPrimary) {
68
+ return {};
69
+ }
70
+ return result;
71
+ }
27
72
  //# sourceMappingURL=repos.js.map
package/dist/repos.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"repos.js","sourceRoot":"","sources":["../src/repos.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAuB;IAEvB,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACxE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAuB;IAEvB,OAAO,MAAM,CAAC,KAAK;SAChB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;SACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAuB;IAClD,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,QAAgB,EAChB,WAAmB,aAAa;IAEhC,OAAO,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"repos.js","sourceRoot":"","sources":["../src/repos.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAG7C;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAuB;IAEvB,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACxE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAuB;IAEvB,OAAO,MAAM,CAAC,KAAK;SAChB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;SACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAuB;IAClD,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,QAAgB,EAChB,WAAmB,aAAa;IAEhC,OAAO,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,CAAS;IAC9B,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAuB,EACvB,cAAsB,EACtB,QAAiB;IAEjB,MAAM,YAAY,GAAG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;IAClE,MAAM,iBAAiB,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;IAExD,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,MAAM,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QAC9D,MAAM,mBAAmB,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC;QAEzD,IAAI,mBAAmB,KAAK,iBAAiB,EAAE,CAAC;YAC9C,YAAY,GAAG,IAAI,CAAC;YACpB,SAAS;QACX,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YAC/B,SAAS;QACX,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,mBAAmB,CAAC;IAC1C,CAAC;IAED,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -16,14 +16,32 @@ export declare const OrchestratorSettingsSchema: z.ZodObject<{
16
16
  labelMonitor: z.ZodOptional<z.ZodBoolean>;
17
17
  webhookSetup: z.ZodOptional<z.ZodBoolean>;
18
18
  smeeChannelUrl: z.ZodOptional<z.ZodString>;
19
+ /**
20
+ * Per-repo override for the validate-phase command. When set, it replaces the
21
+ * orchestrator's global `validateCommand` for jobs in this repo. The global
22
+ * default (`pnpm test && pnpm build`) assumes a `test` script and a monorepo;
23
+ * single-package repos (e.g. an Astro site with only a `build` script) set
24
+ * this to `pnpm build` so the validate phase doesn't fail on a missing script.
25
+ */
26
+ validateCommand: z.ZodOptional<z.ZodString>;
27
+ /**
28
+ * Per-repo override for the pre-validate install command. Empty string skips
29
+ * the install step. When set, it replaces the orchestrator's global
30
+ * `preValidateCommand` for jobs in this repo.
31
+ */
32
+ preValidateCommand: z.ZodOptional<z.ZodString>;
19
33
  }, "strip", z.ZodTypeAny, {
20
34
  labelMonitor?: boolean | undefined;
21
35
  webhookSetup?: boolean | undefined;
22
36
  smeeChannelUrl?: string | undefined;
37
+ validateCommand?: string | undefined;
38
+ preValidateCommand?: string | undefined;
23
39
  }, {
24
40
  labelMonitor?: boolean | undefined;
25
41
  webhookSetup?: boolean | undefined;
26
42
  smeeChannelUrl?: string | undefined;
43
+ validateCommand?: string | undefined;
44
+ preValidateCommand?: string | undefined;
27
45
  }>;
28
46
  export declare const TemplateConfigSchema: z.ZodObject<{
29
47
  project: z.ZodOptional<z.ZodObject<{
@@ -50,14 +68,32 @@ export declare const TemplateConfigSchema: z.ZodObject<{
50
68
  labelMonitor: z.ZodOptional<z.ZodBoolean>;
51
69
  webhookSetup: z.ZodOptional<z.ZodBoolean>;
52
70
  smeeChannelUrl: z.ZodOptional<z.ZodString>;
71
+ /**
72
+ * Per-repo override for the validate-phase command. When set, it replaces the
73
+ * orchestrator's global `validateCommand` for jobs in this repo. The global
74
+ * default (`pnpm test && pnpm build`) assumes a `test` script and a monorepo;
75
+ * single-package repos (e.g. an Astro site with only a `build` script) set
76
+ * this to `pnpm build` so the validate phase doesn't fail on a missing script.
77
+ */
78
+ validateCommand: z.ZodOptional<z.ZodString>;
79
+ /**
80
+ * Per-repo override for the pre-validate install command. Empty string skips
81
+ * the install step. When set, it replaces the orchestrator's global
82
+ * `preValidateCommand` for jobs in this repo.
83
+ */
84
+ preValidateCommand: z.ZodOptional<z.ZodString>;
53
85
  }, "strip", z.ZodTypeAny, {
54
86
  labelMonitor?: boolean | undefined;
55
87
  webhookSetup?: boolean | undefined;
56
88
  smeeChannelUrl?: string | undefined;
89
+ validateCommand?: string | undefined;
90
+ preValidateCommand?: string | undefined;
57
91
  }, {
58
92
  labelMonitor?: boolean | undefined;
59
93
  webhookSetup?: boolean | undefined;
60
94
  smeeChannelUrl?: string | undefined;
95
+ validateCommand?: string | undefined;
96
+ preValidateCommand?: string | undefined;
61
97
  }>>;
62
98
  }, "strip", z.ZodTypeAny, {
63
99
  repos: {
@@ -72,6 +108,8 @@ export declare const TemplateConfigSchema: z.ZodObject<{
72
108
  labelMonitor?: boolean | undefined;
73
109
  webhookSetup?: boolean | undefined;
74
110
  smeeChannelUrl?: string | undefined;
111
+ validateCommand?: string | undefined;
112
+ preValidateCommand?: string | undefined;
75
113
  } | undefined;
76
114
  }, {
77
115
  repos: {
@@ -86,6 +124,8 @@ export declare const TemplateConfigSchema: z.ZodObject<{
86
124
  labelMonitor?: boolean | undefined;
87
125
  webhookSetup?: boolean | undefined;
88
126
  smeeChannelUrl?: string | undefined;
127
+ validateCommand?: string | undefined;
128
+ preValidateCommand?: string | undefined;
89
129
  } | undefined;
90
130
  }>;
91
131
  export type TemplateConfig = z.infer<typeof TemplateConfigSchema>;
@@ -1 +1 @@
1
- {"version":3,"file":"template-schema.d.ts","sourceRoot":"","sources":["../src/template-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;EAI9B,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;EAIrC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAM/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
1
+ {"version":3,"file":"template-schema.d.ts","sourceRoot":"","sources":["../src/template-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;EAI9B,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;IAIrC;;;;;;OAMG;;IAEH;;;;OAIG;;;;;;;;;;;;;;EAEH,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;QAhB/B;;;;;;WAMG;;QAEH;;;;WAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUH,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
@@ -8,6 +8,20 @@ export const OrchestratorSettingsSchema = z.object({
8
8
  labelMonitor: z.boolean().optional(),
9
9
  webhookSetup: z.boolean().optional(),
10
10
  smeeChannelUrl: z.string().url().optional(),
11
+ /**
12
+ * Per-repo override for the validate-phase command. When set, it replaces the
13
+ * orchestrator's global `validateCommand` for jobs in this repo. The global
14
+ * default (`pnpm test && pnpm build`) assumes a `test` script and a monorepo;
15
+ * single-package repos (e.g. an Astro site with only a `build` script) set
16
+ * this to `pnpm build` so the validate phase doesn't fail on a missing script.
17
+ */
18
+ validateCommand: z.string().optional(),
19
+ /**
20
+ * Per-repo override for the pre-validate install command. Empty string skips
21
+ * the install step. When set, it replaces the orchestrator's global
22
+ * `preValidateCommand` for jobs in this repo.
23
+ */
24
+ preValidateCommand: z.string().optional(),
11
25
  });
12
26
  export const TemplateConfigSchema = z.object({
13
27
  project: z.object({
@@ -1 +1 @@
1
- {"version":3,"file":"template-schema.js","sourceRoot":"","sources":["../src/template-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC3F,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;CAC9F,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACpC,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACpC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;CAC5C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;QAChB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAChC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;IAC3B,KAAK,EAAE,mBAAmB;IAC1B,YAAY,EAAE,0BAA0B,CAAC,QAAQ,EAAE;CACpD,CAAC,CAAC"}
1
+ {"version":3,"file":"template-schema.js","sourceRoot":"","sources":["../src/template-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC3F,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;CAC9F,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACpC,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACpC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC3C;;;;;;OAMG;IACH,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACtC;;;;OAIG;IACH,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;QAChB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAChC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;IAC3B,KAAK,EAAE,mBAAmB;IAC1B,YAAY,EAAE,0BAA0B,CAAC,QAAQ,EAAE;CACpD,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@generacy-ai/config",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "Centralized workspace configuration for Generacy monorepo",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",