@wayai/cli 0.1.1 → 0.2.1

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.
@@ -18,6 +18,12 @@ export class ApiClient {
18
18
  direction,
19
19
  });
20
20
  }
21
+ async push(hubId, config) {
22
+ return this.request('POST', '/api/ci/push', {
23
+ hub_id: hubId,
24
+ config,
25
+ });
26
+ }
21
27
  async sync(hubId, branchName, config, commitSha) {
22
28
  return this.request('POST', '/api/ci/sync', {
23
29
  hub_id: hubId,
@@ -29,6 +35,9 @@ export class ApiClient {
29
35
  async lookup(path) {
30
36
  return this.request('GET', `/api/ci/lookup?path=${encodeURIComponent(path)}`);
31
37
  }
38
+ async organizations() {
39
+ return this.request('GET', '/api/ci/organizations');
40
+ }
32
41
  async request(method, path, body) {
33
42
  const url = `${this.apiUrl}${path}`;
34
43
  const headers = {
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,MAAM,OAAO,SAAS;IACZ,MAAM,CAAS;IACf,WAAW,CAAS;IAE5B,YAAY,OAAyB;QACnC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa;QACtB,OAAO,IAAI,CAAC,OAAO,CAAmB,KAAK,EAAE,gBAAgB,KAAK,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,MAAwB,EAAE,YAA6B,MAAM;QACrF,OAAO,IAAI,CAAC,OAAO,CAAiB,MAAM,EAAE,cAAc,EAAE;YAC1D,MAAM,EAAE,KAAK;YACb,MAAM;YACN,SAAS;SACV,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,UAAkB,EAAE,MAAwB,EAAE,SAAkB;QACxF,OAAO,IAAI,CAAC,OAAO,CAAiB,MAAM,EAAE,cAAc,EAAE;YAC1D,MAAM,EAAE,KAAK;YACb,WAAW,EAAE,UAAU;YACvB,MAAM;YACN,UAAU,EAAE,SAAS;SACtB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,OAAO,IAAI,CAAC,OAAO,CAAmB,KAAK,EAAE,uBAAuB,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClG,CAAC;IAEO,KAAK,CAAC,OAAO,CAAI,MAAc,EAAE,IAAY,EAAE,IAAc;QACnE,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;QACpC,MAAM,OAAO,GAA2B;YACtC,aAAa,EAAE,UAAU,IAAI,CAAC,WAAW,EAAE;YAC3C,cAAc,EAAE,kBAAkB;SACnC,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM;YACN,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SAC9C,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,uBAAuB,MAAM,IAAI,IAAI,KAAK,QAAQ,CAAC,MAAM,MAAM,SAAS,EAAE,CAAC,CAAC;QAC9F,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAC;IACvC,CAAC;CACF"}
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH,MAAM,OAAO,SAAS;IACZ,MAAM,CAAS;IACf,WAAW,CAAS;IAE5B,YAAY,OAAyB;QACnC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa;QACtB,OAAO,IAAI,CAAC,OAAO,CAAmB,KAAK,EAAE,gBAAgB,KAAK,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,MAAwB,EAAE,YAA6B,MAAM;QACrF,OAAO,IAAI,CAAC,OAAO,CAAiB,MAAM,EAAE,cAAc,EAAE;YAC1D,MAAM,EAAE,KAAK;YACb,MAAM;YACN,SAAS;SACV,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,MAAwB;QAChD,OAAO,IAAI,CAAC,OAAO,CAAiB,MAAM,EAAE,cAAc,EAAE;YAC1D,MAAM,EAAE,KAAK;YACb,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,UAAkB,EAAE,MAAwB,EAAE,SAAkB;QACxF,OAAO,IAAI,CAAC,OAAO,CAAiB,MAAM,EAAE,cAAc,EAAE;YAC1D,MAAM,EAAE,KAAK;YACb,WAAW,EAAE,UAAU;YACvB,MAAM;YACN,UAAU,EAAE,SAAS;SACtB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,OAAO,IAAI,CAAC,OAAO,CAAmB,KAAK,EAAE,uBAAuB,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClG,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,OAAO,IAAI,CAAC,OAAO,CAA0B,KAAK,EAAE,uBAAuB,CAAC,CAAC;IAC/E,CAAC;IAEO,KAAK,CAAC,OAAO,CAAI,MAAc,EAAE,IAAY,EAAE,IAAc;QACnE,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;QACpC,MAAM,OAAO,GAA2B;YACtC,aAAa,EAAE,UAAU,IAAI,CAAC,WAAW,EAAE;YAC3C,cAAc,EAAE,kBAAkB;SACnC,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM;YACN,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SAC9C,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,uBAAuB,MAAM,IAAI,IAAI,KAAK,QAAQ,CAAC,MAAM,MAAM,SAAS,EAAE,CAAC,CAAC;QAC9F,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAC;IACvC,CAAC;CACF"}
@@ -5,6 +5,7 @@
5
5
  import * as fs from 'node:fs';
6
6
  import * as path from 'node:path';
7
7
  import * as yaml from 'js-yaml';
8
+ import { slugify } from './utils.js';
8
9
  /**
9
10
  * Parse a hub folder into a HubAsCodePayload.
10
11
  * Reads wayai.yaml and resolves agent `instructions` fields that reference
@@ -31,9 +32,7 @@ export function parseHubFolder(hubFolder) {
31
32
  const agents = config.agents?.map((agent) => {
32
33
  const resolved = { ...agent };
33
34
  if (typeof resolved.instructions === 'string' && resolved.instructions.endsWith('.md')) {
34
- // Instructions can be either:
35
- // "agents/pilot.md" (relative to hubFolder — standard format per workspace-format.md)
36
- // "pilot.md" (legacy — just filename, looked up under agents/)
35
+ // Explicit path: "agents/pilot.md" or "pilot.md" (legacy)
37
36
  const instrValue = resolved.instructions;
38
37
  const instructionsPath = instrValue.startsWith('agents/')
39
38
  ? path.join(hubFolder, instrValue)
@@ -45,6 +44,13 @@ export function parseHubFolder(hubFolder) {
45
44
  throw new Error(`Agent instructions file not found: ${instructionsPath} (referenced by agent "${agent.name}")`);
46
45
  }
47
46
  }
47
+ else if (resolved.instructions === undefined && typeof agent.name === 'string') {
48
+ // Convention-based: derive path from agent name slug
49
+ const conventionPath = path.join(hubFolder, 'agents', `${slugify(agent.name)}.md`);
50
+ if (fs.existsSync(conventionPath)) {
51
+ resolved.instructions = fs.readFileSync(conventionPath, 'utf-8');
52
+ }
53
+ }
48
54
  return resolved;
49
55
  });
50
56
  const payload = {
@@ -53,6 +59,10 @@ export function parseHubFolder(hubFolder) {
53
59
  hub_environment: config.hub_environment,
54
60
  hub: config.hub,
55
61
  };
62
+ // Read-only metadata from preview hubs
63
+ if (config.preview_label) {
64
+ payload.preview_label = config.preview_label;
65
+ }
56
66
  if (agents && agents.length > 0) {
57
67
  payload.agents = agents;
58
68
  }
@@ -1 +1 @@
1
- {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/lib/parser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/lib/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Repo-level configuration — .wayai.yaml at git root
3
+ * Scopes the workspace to a single organization.
4
+ */
5
+ export interface RepoConfig {
6
+ organization: string;
7
+ project?: string;
8
+ }
9
+ /**
10
+ * Read .wayai.yaml from the git root. Returns null if not found or invalid.
11
+ */
12
+ export declare function readRepoConfig(root?: string): RepoConfig | null;
13
+ /**
14
+ * Write .wayai.yaml to the git root.
15
+ */
16
+ export declare function writeRepoConfig(config: RepoConfig, root?: string): string;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Repo-level configuration — .wayai.yaml at git root
3
+ * Scopes the workspace to a single organization.
4
+ */
5
+ import * as fs from 'node:fs';
6
+ import * as path from 'node:path';
7
+ import * as yaml from 'js-yaml';
8
+ import { findGitRoot } from './workspace.js';
9
+ /**
10
+ * Read .wayai.yaml from the git root. Returns null if not found or invalid.
11
+ */
12
+ export function readRepoConfig(root) {
13
+ const gitRoot = root ?? findGitRoot();
14
+ if (!gitRoot)
15
+ return null;
16
+ const configPath = path.join(gitRoot, '.wayai.yaml');
17
+ if (!fs.existsSync(configPath))
18
+ return null;
19
+ try {
20
+ const content = fs.readFileSync(configPath, 'utf-8');
21
+ const config = yaml.load(content);
22
+ if (!config?.organization || typeof config.organization !== 'string')
23
+ return null;
24
+ return {
25
+ organization: config.organization,
26
+ project: typeof config.project === 'string' ? config.project : undefined,
27
+ };
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ /**
34
+ * Write .wayai.yaml to the git root.
35
+ */
36
+ export function writeRepoConfig(config, root) {
37
+ const gitRoot = root ?? findGitRoot();
38
+ if (!gitRoot) {
39
+ throw new Error('Not inside a git repository. Run `git init` first.');
40
+ }
41
+ const configPath = path.join(gitRoot, '.wayai.yaml');
42
+ const doc = { organization: config.organization };
43
+ if (config.project)
44
+ doc.project = config.project;
45
+ const content = yaml.dump(doc, { quotingType: '"', forceQuotes: false });
46
+ fs.writeFileSync(configPath, content, 'utf-8');
47
+ return configPath;
48
+ }
49
+ //# sourceMappingURL=repo-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-config.js","sourceRoot":"","sources":["../../src/lib/repo-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAO7C;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAa;IAC1C,MAAM,OAAO,GAAG,IAAI,IAAI,WAAW,EAAE,CAAC;IACtC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACrD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAE5C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAwC,CAAC;QACzE,IAAI,CAAC,MAAM,EAAE,YAAY,IAAI,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAClF,OAAO;YACL,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,OAAO,EAAE,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;SACzE,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,MAAkB,EAAE,IAAa;IAC/D,MAAM,OAAO,GAAG,IAAI,IAAI,WAAW,EAAE,CAAC;IACtC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACrD,MAAM,GAAG,GAA4B,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC;IAC3E,IAAI,MAAM,CAAC,OAAO;QAAE,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAEjD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;IACzE,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAE/C,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -5,6 +5,8 @@ export interface HubAsCodePayload {
5
5
  version: number;
6
6
  hub_id: string;
7
7
  hub_environment: string;
8
+ preview_label?: string | null;
9
+ branch_name?: string | null;
8
10
  hub: {
9
11
  name: string;
10
12
  description?: string;
@@ -32,6 +34,7 @@ export interface HubAsCodePayload {
32
34
  }>;
33
35
  }
34
36
  export interface HubAsCodeAgent {
37
+ id?: string;
35
38
  name: string;
36
39
  role: string;
37
40
  connection: string;
@@ -55,6 +58,7 @@ export interface HubAsCodeAgent {
55
58
  };
56
59
  }
57
60
  export interface HubAsCodeCustomTool {
61
+ id?: string;
58
62
  name: string;
59
63
  description?: string;
60
64
  method?: string;
@@ -68,6 +72,7 @@ export interface HubAsCodeCustomTool {
68
72
  enabled?: boolean;
69
73
  }
70
74
  export interface HubAsCodeState {
75
+ id?: string;
71
76
  name: string;
72
77
  scope: string;
73
78
  description?: string;
@@ -85,9 +90,17 @@ export interface CiLookupResponse {
85
90
  hub_id: string;
86
91
  hub_name: string;
87
92
  hub_environment: string;
93
+ preview_label?: string | null;
94
+ branch_name?: string | null;
88
95
  project_name: string;
89
96
  organization_name: string;
90
97
  }
98
+ export interface CiOrganizationsResponse {
99
+ organizations: Array<{
100
+ id: string;
101
+ name: string;
102
+ }>;
103
+ }
91
104
  export interface CiSyncResponse {
92
105
  preview_hub_id: string;
93
106
  created: boolean;
@@ -1,6 +1,10 @@
1
1
  /**
2
2
  * Shared utility functions
3
3
  */
4
+ /**
5
+ * Prompt the user for yes/no confirmation. Returns true if they answer 'y'.
6
+ */
7
+ export declare function confirm(question: string): Promise<boolean>;
4
8
  /**
5
9
  * Slugify a string: lowercase, normalize accents, replace non-alphanumeric with hyphens.
6
10
  * Matches the slugification rules from workspace-format.md
package/dist/lib/utils.js CHANGED
@@ -1,6 +1,19 @@
1
1
  /**
2
2
  * Shared utility functions
3
3
  */
4
+ import * as readline from 'node:readline';
5
+ /**
6
+ * Prompt the user for yes/no confirmation. Returns true if they answer 'y'.
7
+ */
8
+ export function confirm(question) {
9
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
10
+ return new Promise((resolve) => {
11
+ rl.question(`${question} [y/N]: `, (answer) => {
12
+ rl.close();
13
+ resolve(answer.trim().toLowerCase() === 'y');
14
+ });
15
+ });
16
+ }
4
17
  /**
5
18
  * Slugify a string: lowercase, normalize accents, replace non-alphanumeric with hyphens.
6
19
  * Matches the slugification rules from workspace-format.md
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAO,KAAK;SACT,SAAS,CAAC,KAAK,CAAC;SAChB,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,mBAAmB;SACnD,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAI,6BAA6B;SAC5D,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAY,uBAAuB;SACtD,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAU,wBAAwB;SACvD,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAkB,eAAe;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;IAErC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAC9C,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAwC,CAAC;QACzE,IAAI,MAAM,EAAE,MAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxD,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;QAClD,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAE1C;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,QAAgB;IACtC,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,GAAG,QAAQ,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE;YAC5C,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAO,KAAK;SACT,SAAS,CAAC,KAAK,CAAC;SAChB,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,mBAAmB;SACnD,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAI,6BAA6B;SAC5D,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAY,uBAAuB;SACtD,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAU,wBAAwB;SACvD,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAkB,eAAe;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;IAErC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAC9C,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAwC,CAAC;QACzE,IAAI,MAAM,EAAE,MAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxD,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;QAClD,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Workspace detection and hub resolution for workspace-aware CLI commands.
3
+ *
4
+ * A workspace is a `workspace/` directory at the git root containing
5
+ * project/hub folders, each with a wayai.yaml file.
6
+ */
7
+ export interface HubLocation {
8
+ hubFolder: string;
9
+ hubId: string;
10
+ hubEnvironment: string;
11
+ }
12
+ export interface WorkspaceInfo {
13
+ gitRoot: string;
14
+ workspaceDir: string;
15
+ }
16
+ /**
17
+ * Find the git repository root. Returns null if not inside a git repo.
18
+ */
19
+ export declare function findGitRoot(): string | null;
20
+ /**
21
+ * Detect the workspace directory ({gitRoot}/workspace/).
22
+ * Returns null if not in a git repo or workspace/ doesn't exist.
23
+ */
24
+ export declare function detectWorkspace(): WorkspaceInfo | null;
25
+ /**
26
+ * Scan the workspace directory for hub folders (2 levels: project/hub).
27
+ * Returns metadata for each hub that has a valid wayai.yaml.
28
+ */
29
+ export declare function scanWorkspaceHubs(workspaceDir: string): HubLocation[];
30
+ /**
31
+ * Compute the hub folder slug with preview disambiguation.
32
+ * Production: slugify(hubName)
33
+ * Preview: slugify(hubName) + "-" + slugify(previewLabel || branchName || hubId[0:8])
34
+ *
35
+ * IMPORTANT: This must produce identical output to the backend's computeHubSlug
36
+ * in workers/backend/src/routes/api/ci/lookup.ts. If either changes, update both.
37
+ */
38
+ export declare function getHubFolderSlug(hubName: string, hubEnvironment: string, hubId: string, previewLabel?: string | null, branchName?: string | null): string;
39
+ /**
40
+ * Resolve a hub folder in the workspace by hub_id match (handles folder renames),
41
+ * falling back to slugified project/hub path with preview disambiguation.
42
+ */
43
+ export declare function resolveHubFolder(workspaceDir: string, hubId: string | undefined, projectName: string, hubName: string, hubEnvironment: string, previewLabel?: string | null, branchName?: string | null): string;
44
+ /**
45
+ * Get hub folders with uncommitted changes via `git status`.
46
+ * Filters to wayai.yaml and agents/*.md files under workspace/.
47
+ * Unlike the GitHub Action, does NOT filter by hub_environment.
48
+ */
49
+ export declare function getChangedHubs(workspaceDir: string): HubLocation[];
50
+ export interface ResolvedHubPath {
51
+ hubId: string;
52
+ hubFolder: string;
53
+ hubEnvironment: string;
54
+ }
55
+ /**
56
+ * Parse a hub path (project/hub or org/project/hub), resolve it locally if possible,
57
+ * and return the parsed segments for API fallback if local resolution fails.
58
+ *
59
+ * Returns `{ resolved }` if found locally, or `{ segments }` for API lookup.
60
+ */
61
+ export declare function resolveExplicitHubPath(hubPath: string): {
62
+ resolved: ResolvedHubPath;
63
+ } | {
64
+ segments: {
65
+ orgPrefix?: string;
66
+ project: string;
67
+ hub: string;
68
+ };
69
+ };
70
+ /**
71
+ * Find a hub in the workspace by matching project/hub folder names.
72
+ * Accepts the 2-part path (project/hub) as it appears on disk.
73
+ * Returns the hub location if a matching folder with valid wayai.yaml exists.
74
+ */
75
+ export declare function findHubByFolderPath(workspaceDir: string, projectFolder: string, hubFolder: string): HubLocation | null;
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Workspace detection and hub resolution for workspace-aware CLI commands.
3
+ *
4
+ * A workspace is a `workspace/` directory at the git root containing
5
+ * project/hub folders, each with a wayai.yaml file.
6
+ */
7
+ import { execFileSync } from 'node:child_process';
8
+ import * as fs from 'node:fs';
9
+ import * as path from 'node:path';
10
+ import * as yaml from 'js-yaml';
11
+ import { slugify } from './utils.js';
12
+ /**
13
+ * Find the git repository root. Returns null if not inside a git repo.
14
+ */
15
+ export function findGitRoot() {
16
+ try {
17
+ return execFileSync('git', ['rev-parse', '--show-toplevel'], {
18
+ encoding: 'utf-8',
19
+ stdio: ['pipe', 'pipe', 'pipe'],
20
+ }).trim();
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ }
26
+ /**
27
+ * Detect the workspace directory ({gitRoot}/workspace/).
28
+ * Returns null if not in a git repo or workspace/ doesn't exist.
29
+ */
30
+ export function detectWorkspace() {
31
+ const gitRoot = findGitRoot();
32
+ if (!gitRoot)
33
+ return null;
34
+ const workspaceDir = path.join(gitRoot, 'workspace');
35
+ if (!fs.existsSync(workspaceDir) || !fs.statSync(workspaceDir).isDirectory()) {
36
+ return null;
37
+ }
38
+ return { gitRoot, workspaceDir };
39
+ }
40
+ /**
41
+ * Read hub metadata from a wayai.yaml file.
42
+ * Returns null if the file doesn't exist or lacks required fields.
43
+ */
44
+ function readHubYaml(yamlPath) {
45
+ if (!fs.existsSync(yamlPath))
46
+ return null;
47
+ try {
48
+ const content = fs.readFileSync(yamlPath, 'utf-8');
49
+ const config = yaml.load(content);
50
+ if (!config?.hub_id || !config.hub_environment)
51
+ return null;
52
+ return { hubId: config.hub_id, hubEnvironment: config.hub_environment };
53
+ }
54
+ catch {
55
+ return null;
56
+ }
57
+ }
58
+ /**
59
+ * Scan the workspace directory for hub folders (2 levels: project/hub).
60
+ * Returns metadata for each hub that has a valid wayai.yaml.
61
+ */
62
+ export function scanWorkspaceHubs(workspaceDir) {
63
+ const hubs = [];
64
+ const projects = safeReaddir(workspaceDir);
65
+ for (const project of projects) {
66
+ const projectDir = path.join(workspaceDir, project);
67
+ if (!isDirectory(projectDir))
68
+ continue;
69
+ const hubDirs = safeReaddir(projectDir);
70
+ for (const hub of hubDirs) {
71
+ const hubFolder = path.join(projectDir, hub);
72
+ if (!isDirectory(hubFolder))
73
+ continue;
74
+ const meta = readHubYaml(path.join(hubFolder, 'wayai.yaml'));
75
+ if (meta) {
76
+ hubs.push({ hubFolder, hubId: meta.hubId, hubEnvironment: meta.hubEnvironment });
77
+ }
78
+ }
79
+ }
80
+ return hubs;
81
+ }
82
+ /**
83
+ * Compute the hub folder slug with preview disambiguation.
84
+ * Production: slugify(hubName)
85
+ * Preview: slugify(hubName) + "-" + slugify(previewLabel || branchName || hubId[0:8])
86
+ *
87
+ * IMPORTANT: This must produce identical output to the backend's computeHubSlug
88
+ * in workers/backend/src/routes/api/ci/lookup.ts. If either changes, update both.
89
+ */
90
+ export function getHubFolderSlug(hubName, hubEnvironment, hubId, previewLabel, branchName) {
91
+ const base = slugify(hubName);
92
+ if (hubEnvironment !== 'preview')
93
+ return base;
94
+ const suffix = previewLabel || branchName || hubId.slice(0, 8);
95
+ return `${base}-${slugify(suffix)}`;
96
+ }
97
+ /**
98
+ * Resolve a hub folder in the workspace by hub_id match (handles folder renames),
99
+ * falling back to slugified project/hub path with preview disambiguation.
100
+ */
101
+ export function resolveHubFolder(workspaceDir, hubId, projectName, hubName, hubEnvironment, previewLabel, branchName) {
102
+ // First: try to find by hub_id match (handles folder renames)
103
+ if (hubId) {
104
+ const allHubs = scanWorkspaceHubs(workspaceDir);
105
+ const match = allHubs.find((h) => h.hubId === hubId);
106
+ if (match)
107
+ return match.hubFolder;
108
+ }
109
+ // Fallback: slugified path with preview disambiguation
110
+ const hubFolderSlug = getHubFolderSlug(hubName, hubEnvironment, hubId || '', previewLabel, branchName);
111
+ return path.join(workspaceDir, slugify(projectName), hubFolderSlug);
112
+ }
113
+ /**
114
+ * Get hub folders with uncommitted changes via `git status`.
115
+ * Filters to wayai.yaml and agents/*.md files under workspace/.
116
+ * Unlike the GitHub Action, does NOT filter by hub_environment.
117
+ */
118
+ export function getChangedHubs(workspaceDir) {
119
+ const gitRoot = findGitRoot();
120
+ if (!gitRoot)
121
+ return [];
122
+ // Get workspace path relative to git root for the git status query
123
+ const relWorkspace = path.relative(gitRoot, workspaceDir);
124
+ // Ensure the workspace is inside the git root (no path traversal)
125
+ const normalizedRel = path.normalize(relWorkspace);
126
+ if (normalizedRel.startsWith('..') || path.isAbsolute(normalizedRel)) {
127
+ return [];
128
+ }
129
+ let statusOutput;
130
+ try {
131
+ statusOutput = execFileSync('git', ['status', '--porcelain', '-u', '--', `${relWorkspace}/`], {
132
+ encoding: 'utf-8',
133
+ cwd: gitRoot,
134
+ stdio: ['pipe', 'pipe', 'pipe'],
135
+ });
136
+ }
137
+ catch {
138
+ return [];
139
+ }
140
+ // Split into lines, preserving leading spaces (porcelain status prefix uses them)
141
+ const lines = statusOutput.split('\n').filter((l) => l.length > 0);
142
+ // Extract file paths from porcelain output (skip the 2-char status + space prefix)
143
+ const changedFiles = lines.map((line) => {
144
+ // Porcelain format: "XY file" or "XY orig -> file" (for renames)
145
+ const filePart = line.slice(3);
146
+ // Handle renames: "orig -> dest"
147
+ const arrowIdx = filePart.indexOf(' -> ');
148
+ return arrowIdx >= 0 ? filePart.slice(arrowIdx + 4) : filePart;
149
+ });
150
+ // Filter to hub config files
151
+ const hubFiles = changedFiles.filter((file) => {
152
+ return file.endsWith('/wayai.yaml') || file.endsWith('wayai.yaml') || /\/agents\/[^/]+\.md$/.test(file);
153
+ });
154
+ if (hubFiles.length === 0)
155
+ return [];
156
+ // Extract unique hub folder paths (absolute)
157
+ const hubFolders = new Set();
158
+ for (const file of hubFiles) {
159
+ const absFile = path.resolve(gitRoot, file);
160
+ if (file.endsWith('wayai.yaml')) {
161
+ hubFolders.add(path.dirname(absFile));
162
+ }
163
+ else if (file.includes('/agents/')) {
164
+ const agentsIndex = absFile.lastIndexOf('/agents/');
165
+ hubFolders.add(absFile.substring(0, agentsIndex));
166
+ }
167
+ }
168
+ // Read each hub folder's wayai.yaml
169
+ const hubs = [];
170
+ for (const hubFolder of hubFolders) {
171
+ const meta = readHubYaml(path.join(hubFolder, 'wayai.yaml'));
172
+ if (meta) {
173
+ hubs.push({ hubFolder, hubId: meta.hubId, hubEnvironment: meta.hubEnvironment });
174
+ }
175
+ }
176
+ return hubs;
177
+ }
178
+ /**
179
+ * Parse a hub path (project/hub or org/project/hub), resolve it locally if possible,
180
+ * and return the parsed segments for API fallback if local resolution fails.
181
+ *
182
+ * Returns `{ resolved }` if found locally, or `{ segments }` for API lookup.
183
+ */
184
+ export function resolveExplicitHubPath(hubPath) {
185
+ const parts = hubPath.split('/');
186
+ let projectSegment;
187
+ let hubSegment;
188
+ let orgPrefix;
189
+ if (parts.length === 2) {
190
+ [projectSegment, hubSegment] = parts;
191
+ }
192
+ else if (parts.length === 3) {
193
+ [orgPrefix, projectSegment, hubSegment] = parts;
194
+ }
195
+ else {
196
+ throw new Error('Hub path must be project/hub or org/project/hub');
197
+ }
198
+ // Try local workspace resolution first (avoids API call, handles slugified folder names)
199
+ const workspace = detectWorkspace();
200
+ if (workspace) {
201
+ const local = findHubByFolderPath(workspace.workspaceDir, projectSegment, hubSegment);
202
+ if (local) {
203
+ return {
204
+ resolved: {
205
+ hubId: local.hubId,
206
+ hubFolder: local.hubFolder,
207
+ hubEnvironment: local.hubEnvironment,
208
+ },
209
+ };
210
+ }
211
+ }
212
+ return { segments: { orgPrefix, project: projectSegment, hub: hubSegment } };
213
+ }
214
+ /**
215
+ * Find a hub in the workspace by matching project/hub folder names.
216
+ * Accepts the 2-part path (project/hub) as it appears on disk.
217
+ * Returns the hub location if a matching folder with valid wayai.yaml exists.
218
+ */
219
+ export function findHubByFolderPath(workspaceDir, projectFolder, hubFolder) {
220
+ const candidate = path.join(workspaceDir, projectFolder, hubFolder);
221
+ if (!isDirectory(candidate))
222
+ return null;
223
+ const meta = readHubYaml(path.join(candidate, 'wayai.yaml'));
224
+ if (!meta)
225
+ return null;
226
+ return { hubFolder: candidate, hubId: meta.hubId, hubEnvironment: meta.hubEnvironment };
227
+ }
228
+ function isDirectory(p) {
229
+ try {
230
+ return fs.statSync(p).isDirectory();
231
+ }
232
+ catch {
233
+ return false;
234
+ }
235
+ }
236
+ function safeReaddir(dir) {
237
+ try {
238
+ return fs.readdirSync(dir).filter((entry) => !entry.startsWith('.'));
239
+ }
240
+ catch {
241
+ return [];
242
+ }
243
+ }
244
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/lib/workspace.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Unit tests for resolveExplicitHubPath and findHubByFolderPath
3
+ * using vi.mock to mock filesystem and child_process dependencies.
4
+ */
5
+ export {};