@agent-native/core 0.7.57 → 0.7.59

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 (38) hide show
  1. package/dist/a2a/artifact-response.d.ts.map +1 -1
  2. package/dist/a2a/artifact-response.js +24 -3
  3. package/dist/a2a/artifact-response.js.map +1 -1
  4. package/dist/a2a/client.d.ts.map +1 -1
  5. package/dist/a2a/client.js +27 -5
  6. package/dist/a2a/client.js.map +1 -1
  7. package/dist/cli/create.d.ts.map +1 -1
  8. package/dist/cli/create.js +2 -0
  9. package/dist/cli/create.js.map +1 -1
  10. package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
  11. package/dist/client/NewWorkspaceAppFlow.js +34 -38
  12. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  13. package/dist/deploy/workspace-deploy.d.ts.map +1 -1
  14. package/dist/deploy/workspace-deploy.js +7 -20
  15. package/dist/deploy/workspace-deploy.js.map +1 -1
  16. package/dist/integrations/a2a-continuation-processor.d.ts.map +1 -1
  17. package/dist/integrations/a2a-continuation-processor.js +17 -1
  18. package/dist/integrations/a2a-continuation-processor.js.map +1 -1
  19. package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
  20. package/dist/integrations/a2a-continuations-store.js +14 -5
  21. package/dist/integrations/a2a-continuations-store.js.map +1 -1
  22. package/dist/integrations/webhook-handler.js +22 -1
  23. package/dist/integrations/webhook-handler.js.map +1 -1
  24. package/dist/shared/workspace-app-id.d.ts +1 -1
  25. package/dist/shared/workspace-app-id.d.ts.map +1 -1
  26. package/dist/shared/workspace-app-id.js +2 -0
  27. package/dist/shared/workspace-app-id.js.map +1 -1
  28. package/dist/templates/workspace-root/.env.example +6 -0
  29. package/dist/templates/workspace-root/AGENTS.md +50 -0
  30. package/dist/templates/workspace-root/README.md +18 -1
  31. package/dist/templates/workspace-root/package.json +2 -0
  32. package/dist/templates/workspace-root/scripts/repair-workspace-org.ts +283 -0
  33. package/package.json +1 -1
  34. package/src/templates/workspace-root/.env.example +6 -0
  35. package/src/templates/workspace-root/AGENTS.md +50 -0
  36. package/src/templates/workspace-root/README.md +18 -1
  37. package/src/templates/workspace-root/package.json +2 -0
  38. package/src/templates/workspace-root/scripts/repair-workspace-org.ts +283 -0
@@ -0,0 +1,283 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ import crypto from "node:crypto";
4
+ import fs from "node:fs";
5
+ import path from "node:path";
6
+
7
+ interface Options {
8
+ name?: string;
9
+ domain?: string;
10
+ ownerEmail?: string;
11
+ a2aSecret?: string;
12
+ envPath: string;
13
+ force: boolean;
14
+ dryRun: boolean;
15
+ setDispatchDefaultOwner: boolean;
16
+ }
17
+
18
+ const HELP = `Usage:
19
+ pnpm repair:workspace-org -- --name "Example Co" --domain example.com --owner-email owner@example.com
20
+
21
+ Options:
22
+ --name <value> Sets WORKSPACE_ORG_NAME
23
+ --domain <value> Sets WORKSPACE_ORG_DOMAIN
24
+ --owner-email <value> Sets WORKSPACE_OWNER_EMAIL
25
+ --a2a-secret <value> Sets A2A_SECRET (generated when omitted)
26
+ --env <path> Env file to update (default: .env)
27
+ --force Overwrite existing non-empty values
28
+ --dry-run Print the changes without writing
29
+ --set-dispatch-default-owner Also set DISPATCH_DEFAULT_OWNER_EMAIL
30
+ `;
31
+
32
+ const REQUIRED_KEYS = [
33
+ "WORKSPACE_ORG_NAME",
34
+ "WORKSPACE_ORG_DOMAIN",
35
+ "WORKSPACE_OWNER_EMAIL",
36
+ "A2A_SECRET",
37
+ ] as const;
38
+
39
+ type RequiredKey = (typeof REQUIRED_KEYS)[number];
40
+
41
+ function parseArgs(argv: string[]): Options {
42
+ const opts: Options = {
43
+ envPath: ".env",
44
+ force: false,
45
+ dryRun: false,
46
+ setDispatchDefaultOwner: false,
47
+ };
48
+
49
+ for (let i = 0; i < argv.length; i++) {
50
+ const arg = argv[i];
51
+ const [flag, inline] = arg.includes("=")
52
+ ? arg.split(/=(.*)/s, 2)
53
+ : [arg, undefined];
54
+ const value = (): string => {
55
+ const next = inline ?? argv[++i];
56
+ if (!next) fail(`Missing value for ${flag}.`);
57
+ return next;
58
+ };
59
+
60
+ switch (flag) {
61
+ case "--help":
62
+ case "-h":
63
+ console.log(HELP);
64
+ process.exit(0);
65
+ case "--name":
66
+ opts.name = value();
67
+ break;
68
+ case "--domain":
69
+ opts.domain = value();
70
+ break;
71
+ case "--owner-email":
72
+ opts.ownerEmail = value();
73
+ break;
74
+ case "--a2a-secret":
75
+ opts.a2aSecret = value();
76
+ break;
77
+ case "--env":
78
+ opts.envPath = value();
79
+ break;
80
+ case "--force":
81
+ opts.force = true;
82
+ break;
83
+ case "--dry-run":
84
+ opts.dryRun = true;
85
+ break;
86
+ case "--set-dispatch-default-owner":
87
+ opts.setDispatchDefaultOwner = true;
88
+ break;
89
+ default:
90
+ fail(`Unknown option: ${arg}\n\n${HELP}`);
91
+ }
92
+ }
93
+
94
+ return opts;
95
+ }
96
+
97
+ function fail(message: string): never {
98
+ console.error(message);
99
+ process.exit(1);
100
+ }
101
+
102
+ function readEnvFile(envPath: string): string {
103
+ if (fs.existsSync(envPath)) return fs.readFileSync(envPath, "utf-8");
104
+ const examplePath = path.join(path.dirname(envPath), ".env.example");
105
+ if (fs.existsSync(examplePath)) return fs.readFileSync(examplePath, "utf-8");
106
+ return "";
107
+ }
108
+
109
+ function parseEnv(content: string): Record<string, string> {
110
+ const values: Record<string, string> = {};
111
+ for (const line of content.split(/\r?\n/)) {
112
+ const match = line.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*)\s*$/);
113
+ if (!match) continue;
114
+ values[match[1]] = unquote(match[2]);
115
+ }
116
+ return values;
117
+ }
118
+
119
+ function unquote(value: string): string {
120
+ const trimmed = value.trim();
121
+ if (
122
+ (trimmed.startsWith('"') && trimmed.endsWith('"')) ||
123
+ (trimmed.startsWith("'") && trimmed.endsWith("'"))
124
+ ) {
125
+ return trimmed.slice(1, -1);
126
+ }
127
+ return trimmed;
128
+ }
129
+
130
+ function normalizeDomain(domain: string): string {
131
+ return domain
132
+ .trim()
133
+ .toLowerCase()
134
+ .replace(/^https?:\/\//, "")
135
+ .replace(/\/.*$/, "");
136
+ }
137
+
138
+ function validateDomain(domain: string): void {
139
+ if (!/^([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z]{2,}$/.test(domain)) {
140
+ fail(`Invalid --domain "${domain}". Use a bare domain like example.com.`);
141
+ }
142
+ }
143
+
144
+ function validateEmail(email: string): void {
145
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
146
+ fail(`Invalid --owner-email "${email}".`);
147
+ }
148
+ }
149
+
150
+ function formatEnvValue(value: string): string {
151
+ if (/^[A-Za-z0-9_@./:+-]+$/.test(value)) return value;
152
+ return JSON.stringify(value);
153
+ }
154
+
155
+ function upsertEnvValue(
156
+ content: string,
157
+ key: string,
158
+ value: string,
159
+ force: boolean,
160
+ ): { content: string; changed: boolean; skipped: boolean } {
161
+ const lines = content.length > 0 ? content.split(/\r?\n/) : [];
162
+ let found = false;
163
+ let changed = false;
164
+ let skipped = false;
165
+
166
+ const next = lines.map((line) => {
167
+ const match = line.match(/^(\s*)([A-Z0-9_]+)(\s*=\s*)(.*)$/);
168
+ if (!match || match[2] !== key) return line;
169
+
170
+ found = true;
171
+ const existing = unquote(match[4]);
172
+ if (existing && !force) {
173
+ skipped = true;
174
+ return line;
175
+ }
176
+
177
+ const replacement = `${match[1]}${key}${match[3]}${formatEnvValue(value)}`;
178
+ if (replacement !== line) changed = true;
179
+ return replacement;
180
+ });
181
+
182
+ if (!found) {
183
+ if (next.length > 0 && next[next.length - 1] !== "") next.push("");
184
+ next.push(`${key}=${formatEnvValue(value)}`);
185
+ changed = true;
186
+ }
187
+
188
+ return { content: next.join("\n"), changed, skipped };
189
+ }
190
+
191
+ function firstValue(...values: Array<string | undefined>): string | undefined {
192
+ return values.map((v) => v?.trim()).find(Boolean);
193
+ }
194
+
195
+ function main(): void {
196
+ const opts = parseArgs(process.argv.slice(2));
197
+ const envPath = path.resolve(opts.envPath);
198
+ const original = readEnvFile(envPath);
199
+ const current = parseEnv(original);
200
+
201
+ const name = firstValue(
202
+ opts.name,
203
+ process.env.WORKSPACE_ORG_NAME,
204
+ current.WORKSPACE_ORG_NAME,
205
+ );
206
+ const rawDomain = firstValue(
207
+ opts.domain,
208
+ process.env.WORKSPACE_ORG_DOMAIN,
209
+ current.WORKSPACE_ORG_DOMAIN,
210
+ );
211
+ const ownerEmail = firstValue(
212
+ opts.ownerEmail,
213
+ process.env.WORKSPACE_OWNER_EMAIL,
214
+ current.WORKSPACE_OWNER_EMAIL,
215
+ )?.toLowerCase();
216
+ const a2aSecret =
217
+ firstValue(opts.a2aSecret, process.env.A2A_SECRET, current.A2A_SECRET) ??
218
+ crypto.randomBytes(32).toString("hex");
219
+
220
+ if (!name) fail("--name or WORKSPACE_ORG_NAME is required.");
221
+ if (!rawDomain) fail("--domain or WORKSPACE_ORG_DOMAIN is required.");
222
+ if (!ownerEmail) fail("--owner-email or WORKSPACE_OWNER_EMAIL is required.");
223
+
224
+ const domain = normalizeDomain(rawDomain);
225
+ validateDomain(domain);
226
+ validateEmail(ownerEmail);
227
+
228
+ const desired: Record<RequiredKey, string> = {
229
+ WORKSPACE_ORG_NAME: name,
230
+ WORKSPACE_ORG_DOMAIN: domain,
231
+ WORKSPACE_OWNER_EMAIL: ownerEmail,
232
+ A2A_SECRET: a2aSecret,
233
+ };
234
+
235
+ let next = original.trimEnd();
236
+ const changed: string[] = [];
237
+ const skipped: string[] = [];
238
+
239
+ for (const key of REQUIRED_KEYS) {
240
+ const result = upsertEnvValue(next, key, desired[key], opts.force);
241
+ next = result.content;
242
+ if (result.changed) changed.push(key);
243
+ if (result.skipped) skipped.push(key);
244
+ }
245
+
246
+ if (opts.setDispatchDefaultOwner) {
247
+ const result = upsertEnvValue(
248
+ next,
249
+ "DISPATCH_DEFAULT_OWNER_EMAIL",
250
+ ownerEmail,
251
+ opts.force,
252
+ );
253
+ next = result.content;
254
+ if (result.changed) changed.push("DISPATCH_DEFAULT_OWNER_EMAIL");
255
+ if (result.skipped) skipped.push("DISPATCH_DEFAULT_OWNER_EMAIL");
256
+ }
257
+
258
+ next = next.trimEnd() + "\n";
259
+
260
+ if (opts.dryRun) {
261
+ console.log(next);
262
+ } else {
263
+ fs.writeFileSync(envPath, next);
264
+ }
265
+
266
+ console.log(
267
+ `${opts.dryRun ? "Validated" : "Updated"} ${path.relative(process.cwd(), envPath) || envPath}.`,
268
+ );
269
+ if (changed.length > 0) console.log(`Changed: ${changed.join(", ")}`);
270
+ if (skipped.length > 0) {
271
+ console.log(
272
+ `Kept existing values: ${skipped.join(", ")} (use --force to overwrite)`,
273
+ );
274
+ }
275
+ console.log("");
276
+ console.log("Next steps:");
277
+ console.log("1. Sign in as WORKSPACE_OWNER_EMAIL.");
278
+ console.log("2. Create or select the org named by WORKSPACE_ORG_NAME.");
279
+ console.log("3. Set the org allowed domain to WORKSPACE_ORG_DOMAIN.");
280
+ console.log("4. Set or sync the org A2A secret from A2A_SECRET across apps.");
281
+ }
282
+
283
+ main();