@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.
- package/dist/a2a/artifact-response.d.ts.map +1 -1
- package/dist/a2a/artifact-response.js +24 -3
- package/dist/a2a/artifact-response.js.map +1 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +27 -5
- package/dist/a2a/client.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +2 -0
- package/dist/cli/create.js.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.js +34 -38
- package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
- package/dist/deploy/workspace-deploy.d.ts.map +1 -1
- package/dist/deploy/workspace-deploy.js +7 -20
- package/dist/deploy/workspace-deploy.js.map +1 -1
- package/dist/integrations/a2a-continuation-processor.d.ts.map +1 -1
- package/dist/integrations/a2a-continuation-processor.js +17 -1
- package/dist/integrations/a2a-continuation-processor.js.map +1 -1
- package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
- package/dist/integrations/a2a-continuations-store.js +14 -5
- package/dist/integrations/a2a-continuations-store.js.map +1 -1
- package/dist/integrations/webhook-handler.js +22 -1
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/shared/workspace-app-id.d.ts +1 -1
- package/dist/shared/workspace-app-id.d.ts.map +1 -1
- package/dist/shared/workspace-app-id.js +2 -0
- package/dist/shared/workspace-app-id.js.map +1 -1
- package/dist/templates/workspace-root/.env.example +6 -0
- package/dist/templates/workspace-root/AGENTS.md +50 -0
- package/dist/templates/workspace-root/README.md +18 -1
- package/dist/templates/workspace-root/package.json +2 -0
- package/dist/templates/workspace-root/scripts/repair-workspace-org.ts +283 -0
- package/package.json +1 -1
- package/src/templates/workspace-root/.env.example +6 -0
- package/src/templates/workspace-root/AGENTS.md +50 -0
- package/src/templates/workspace-root/README.md +18 -1
- package/src/templates/workspace-root/package.json +2 -0
- 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();
|