@everfir/az8-cli 0.4.0 → 0.5.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.
- package/README.md +14 -16
- package/dist/main.js +264 -251
- package/package.json +2 -4
- package/skills/az8-cli/SKILL.md +18 -20
- package/CHANGELOG.md +0 -260
- package/RELEASE.md +0 -93
package/dist/main.js
CHANGED
|
@@ -2387,7 +2387,7 @@ var require_websocket = __commonJS({
|
|
|
2387
2387
|
var http = __require("http");
|
|
2388
2388
|
var net2 = __require("net");
|
|
2389
2389
|
var tls = __require("tls");
|
|
2390
|
-
var { randomBytes: randomBytes2, createHash:
|
|
2390
|
+
var { randomBytes: randomBytes2, createHash: createHash9 } = __require("crypto");
|
|
2391
2391
|
var { Duplex, Readable } = __require("stream");
|
|
2392
2392
|
var { URL: URL2 } = __require("url");
|
|
2393
2393
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -3047,7 +3047,7 @@ var require_websocket = __commonJS({
|
|
|
3047
3047
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
3048
3048
|
return;
|
|
3049
3049
|
}
|
|
3050
|
-
const digest =
|
|
3050
|
+
const digest = createHash9("sha1").update(key + GUID).digest("base64");
|
|
3051
3051
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
3052
3052
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
3053
3053
|
return;
|
|
@@ -3414,7 +3414,7 @@ var require_websocket_server = __commonJS({
|
|
|
3414
3414
|
var EventEmitter3 = __require("events");
|
|
3415
3415
|
var http = __require("http");
|
|
3416
3416
|
var { Duplex } = __require("stream");
|
|
3417
|
-
var { createHash:
|
|
3417
|
+
var { createHash: createHash9 } = __require("crypto");
|
|
3418
3418
|
var extension2 = require_extension();
|
|
3419
3419
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
3420
3420
|
var subprotocol2 = require_subprotocol();
|
|
@@ -3715,7 +3715,7 @@ var require_websocket_server = __commonJS({
|
|
|
3715
3715
|
);
|
|
3716
3716
|
}
|
|
3717
3717
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
3718
|
-
const digest =
|
|
3718
|
+
const digest = createHash9("sha1").update(key + GUID).digest("base64");
|
|
3719
3719
|
const headers = [
|
|
3720
3720
|
"HTTP/1.1 101 Switching Protocols",
|
|
3721
3721
|
"Upgrade: websocket",
|
|
@@ -19224,7 +19224,7 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
19224
19224
|
import { chmod, lstat, mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
19225
19225
|
import { homedir } from "node:os";
|
|
19226
19226
|
import path from "node:path";
|
|
19227
|
-
var FORMAT = "az8.workflow-preference.
|
|
19227
|
+
var FORMAT = "az8.workflow-preference.v2";
|
|
19228
19228
|
function createNodeWorkflowPreferenceStore(options) {
|
|
19229
19229
|
const accountId = options.accountId.trim();
|
|
19230
19230
|
if (!accountId) throw new Error("Workflow preference scope requires an account id.");
|
|
@@ -19236,12 +19236,12 @@ function createNodeWorkflowPreferenceStore(options) {
|
|
|
19236
19236
|
return {
|
|
19237
19237
|
async read(contentType) {
|
|
19238
19238
|
await ensurePrivateDirectory(directory);
|
|
19239
|
-
const filePath = preferencePath(directory, options.
|
|
19239
|
+
const filePath = preferencePath(directory, options.targetKey, accountId, contentType);
|
|
19240
19240
|
try {
|
|
19241
19241
|
await assertPrivateRegularFile(filePath);
|
|
19242
19242
|
return parseStoredPreference(
|
|
19243
19243
|
JSON.parse(await readFile(filePath, "utf8")),
|
|
19244
|
-
options.
|
|
19244
|
+
options.targetKey,
|
|
19245
19245
|
accountId,
|
|
19246
19246
|
contentType
|
|
19247
19247
|
);
|
|
@@ -19256,19 +19256,19 @@ function createNodeWorkflowPreferenceStore(options) {
|
|
|
19256
19256
|
const value = {
|
|
19257
19257
|
accountId,
|
|
19258
19258
|
contentType,
|
|
19259
|
-
environment: options.environment,
|
|
19260
19259
|
format: FORMAT,
|
|
19261
|
-
preference: normalized
|
|
19260
|
+
preference: normalized,
|
|
19261
|
+
targetKey: options.targetKey
|
|
19262
19262
|
};
|
|
19263
19263
|
await writeJsonAtomic(
|
|
19264
|
-
preferencePath(directory, options.
|
|
19264
|
+
preferencePath(directory, options.targetKey, accountId, contentType),
|
|
19265
19265
|
value
|
|
19266
19266
|
);
|
|
19267
19267
|
}
|
|
19268
19268
|
};
|
|
19269
19269
|
}
|
|
19270
|
-
function parseStoredPreference(value,
|
|
19271
|
-
if (!isRecord2(value) || value.format !== FORMAT || value.
|
|
19270
|
+
function parseStoredPreference(value, targetKey, accountId, contentType) {
|
|
19271
|
+
if (!isRecord2(value) || value.format !== FORMAT || value.targetKey !== targetKey || value.accountId !== accountId || value.contentType !== contentType) {
|
|
19272
19272
|
return null;
|
|
19273
19273
|
}
|
|
19274
19274
|
try {
|
|
@@ -19289,8 +19289,8 @@ function normalizePreference(value) {
|
|
|
19289
19289
|
);
|
|
19290
19290
|
return { config: config2, definitionId: value.definitionId.trim() };
|
|
19291
19291
|
}
|
|
19292
|
-
function preferencePath(directory,
|
|
19293
|
-
const digest = createHash("sha256").update(`${
|
|
19292
|
+
function preferencePath(directory, targetKey, accountId, contentType) {
|
|
19293
|
+
const digest = createHash("sha256").update(`${targetKey}\0${accountId}\0${contentType}`).digest("hex");
|
|
19294
19294
|
return path.join(directory, `${digest}.json`);
|
|
19295
19295
|
}
|
|
19296
19296
|
async function ensurePrivateDirectory(directory) {
|
|
@@ -34079,7 +34079,6 @@ var accountSchema = external_exports.object({
|
|
|
34079
34079
|
var createdAuthorizationSchema = external_exports.object({
|
|
34080
34080
|
created_at: external_exports.number().int(),
|
|
34081
34081
|
device_code: external_exports.string().min(1),
|
|
34082
|
-
environment: external_exports.enum(["production", "test"]),
|
|
34083
34082
|
expires_at: external_exports.number().int(),
|
|
34084
34083
|
expires_in: external_exports.number().int().positive(),
|
|
34085
34084
|
format: external_exports.literal("az8.cli-authorization.v1"),
|
|
@@ -39981,7 +39980,7 @@ var CanvasClient = class {
|
|
|
39981
39980
|
this.session = session ?? new CanvasSession(config2, projectId, void 0, {
|
|
39982
39981
|
workflowPreferences: (actor) => createNodeWorkflowPreferenceStore({
|
|
39983
39982
|
accountId: actor.accountId,
|
|
39984
|
-
|
|
39983
|
+
targetKey: config2.targetKey
|
|
39985
39984
|
})
|
|
39986
39985
|
});
|
|
39987
39986
|
}
|
|
@@ -40157,15 +40156,17 @@ function readTimedOut(value) {
|
|
|
40157
40156
|
}
|
|
40158
40157
|
|
|
40159
40158
|
// src/cli/config.ts
|
|
40159
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
40160
40160
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
40161
40161
|
import path4 from "node:path";
|
|
40162
40162
|
|
|
40163
40163
|
// src/auth/local-credential-store.ts
|
|
40164
|
-
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
40165
|
-
import { chmod as chmod2, lstat as lstat3, mkdir as mkdir2, readFile as readFile2, rename as rename2, unlink, writeFile as writeFile2 } from "node:fs/promises";
|
|
40164
|
+
import { createHash as createHash4, randomUUID as randomUUID2 } from "node:crypto";
|
|
40165
|
+
import { chmod as chmod2, lstat as lstat3, mkdir as mkdir2, readdir, readFile as readFile2, rename as rename2, unlink, writeFile as writeFile2 } from "node:fs/promises";
|
|
40166
40166
|
import { homedir as homedir2 } from "node:os";
|
|
40167
40167
|
import path3 from "node:path";
|
|
40168
|
-
var LOCAL_CREDENTIAL_FORMAT = "az8.local-credential.
|
|
40168
|
+
var LOCAL_CREDENTIAL_FORMAT = "az8.local-credential.v2";
|
|
40169
|
+
var TARGET_KEY_PATTERN = /^[0-9a-f]{64}$/;
|
|
40169
40170
|
var LocalCredentialStore = class {
|
|
40170
40171
|
stateRoot;
|
|
40171
40172
|
constructor(options = {}) {
|
|
@@ -40174,35 +40175,47 @@ var LocalCredentialStore = class {
|
|
|
40174
40175
|
options.stateRoot ?? env.AZ8_CLI_STATE_DIR ?? path3.join(env.XDG_STATE_HOME ?? path3.join(homedir2(), ".local", "state"), "az8-cli")
|
|
40175
40176
|
);
|
|
40176
40177
|
}
|
|
40177
|
-
async read(
|
|
40178
|
+
async read(targetKey) {
|
|
40178
40179
|
await this.initialize();
|
|
40179
|
-
const filePath = this.filePath(
|
|
40180
|
+
const filePath = this.filePath(targetKey);
|
|
40180
40181
|
try {
|
|
40181
40182
|
await assertPrivateRegularFile2(filePath);
|
|
40182
|
-
return parseCredential(JSON.parse(await readFile2(filePath, "utf8")),
|
|
40183
|
+
return parseCredential(JSON.parse(await readFile2(filePath, "utf8")), targetKey);
|
|
40183
40184
|
} catch (error51) {
|
|
40184
40185
|
if (error51.code === "ENOENT") return null;
|
|
40185
40186
|
throw credentialError(
|
|
40186
40187
|
"invalid-local-credential",
|
|
40187
|
-
|
|
40188
|
+
"The stored credential for the configured AZ8 service is unavailable or invalid. Run az8 login."
|
|
40188
40189
|
);
|
|
40189
40190
|
}
|
|
40190
40191
|
}
|
|
40191
40192
|
async write(credential) {
|
|
40192
|
-
const normalized = parseCredential(credential, credential.
|
|
40193
|
+
const normalized = parseCredential(credential, credential.targetKey);
|
|
40194
|
+
await this.initialize();
|
|
40195
|
+
await writeJsonAtomic2(this.filePath(normalized.targetKey), normalized);
|
|
40196
|
+
}
|
|
40197
|
+
async list() {
|
|
40193
40198
|
await this.initialize();
|
|
40194
|
-
await
|
|
40199
|
+
const entries = await readdir(path3.join(this.stateRoot, "credentials"));
|
|
40200
|
+
const credentials = [];
|
|
40201
|
+
for (const entry of entries.sort()) {
|
|
40202
|
+
const targetKey = entry.endsWith(".json") ? entry.slice(0, -5) : "";
|
|
40203
|
+
if (!TARGET_KEY_PATTERN.test(targetKey)) continue;
|
|
40204
|
+
const credential = await this.read(targetKey);
|
|
40205
|
+
if (credential) credentials.push(credential);
|
|
40206
|
+
}
|
|
40207
|
+
return credentials;
|
|
40195
40208
|
}
|
|
40196
|
-
async delete(
|
|
40209
|
+
async delete(targetKey) {
|
|
40197
40210
|
await this.initialize();
|
|
40198
40211
|
try {
|
|
40199
|
-
await unlink(this.filePath(
|
|
40212
|
+
await unlink(this.filePath(targetKey));
|
|
40200
40213
|
return true;
|
|
40201
40214
|
} catch (error51) {
|
|
40202
40215
|
if (error51.code === "ENOENT") return false;
|
|
40203
40216
|
throw credentialError(
|
|
40204
40217
|
"local-credential-delete-failed",
|
|
40205
|
-
|
|
40218
|
+
"Unable to remove the stored credential for the configured AZ8 service."
|
|
40206
40219
|
);
|
|
40207
40220
|
}
|
|
40208
40221
|
}
|
|
@@ -40210,12 +40223,15 @@ var LocalCredentialStore = class {
|
|
|
40210
40223
|
await ensurePrivateDirectory2(this.stateRoot);
|
|
40211
40224
|
await ensurePrivateDirectory2(path3.join(this.stateRoot, "credentials"));
|
|
40212
40225
|
}
|
|
40213
|
-
filePath(
|
|
40214
|
-
|
|
40226
|
+
filePath(targetKey) {
|
|
40227
|
+
if (!TARGET_KEY_PATTERN.test(targetKey)) {
|
|
40228
|
+
throw credentialError("invalid-service-target", "AZ8 service target identity is invalid.");
|
|
40229
|
+
}
|
|
40230
|
+
return path3.join(this.stateRoot, "credentials", `${targetKey}.json`);
|
|
40215
40231
|
}
|
|
40216
40232
|
};
|
|
40217
|
-
function parseCredential(value,
|
|
40218
|
-
if (!isRecord5(value) || value.format !== LOCAL_CREDENTIAL_FORMAT || value.
|
|
40233
|
+
function parseCredential(value, targetKey) {
|
|
40234
|
+
if (!isRecord5(value) || value.format !== LOCAL_CREDENTIAL_FORMAT || value.targetKey !== targetKey || !TARGET_KEY_PATTERN.test(targetKey) || typeof value.baseUrl !== "string" || !value.baseUrl || createHash4("sha256").update(value.baseUrl).digest("hex") !== targetKey || typeof value.token !== "string" || !isSafeToken(value.token) || typeof value.updatedAt !== "string" || !isRecord5(value.account) || typeof value.account.accountId !== "string" || !value.account.accountId.trim() || typeof value.account.email !== "string" || !value.account.email.trim() || value.account.nickname !== void 0 && typeof value.account.nickname !== "string" || value.account.subscriptionType !== void 0 && typeof value.account.subscriptionType !== "string" || value.tokenExpiresAt !== void 0 && (typeof value.tokenExpiresAt !== "number" || !Number.isInteger(value.tokenExpiresAt) || value.tokenExpiresAt <= 0)) {
|
|
40219
40235
|
throw credentialError("invalid-local-credential", "Stored credential is invalid.");
|
|
40220
40236
|
}
|
|
40221
40237
|
return {
|
|
@@ -40225,8 +40241,9 @@ function parseCredential(value, environment) {
|
|
|
40225
40241
|
...value.account.nickname === void 0 ? {} : { nickname: value.account.nickname },
|
|
40226
40242
|
...value.account.subscriptionType === void 0 ? {} : { subscriptionType: value.account.subscriptionType }
|
|
40227
40243
|
},
|
|
40228
|
-
|
|
40244
|
+
baseUrl: value.baseUrl,
|
|
40229
40245
|
format: LOCAL_CREDENTIAL_FORMAT,
|
|
40246
|
+
targetKey,
|
|
40230
40247
|
token: value.token,
|
|
40231
40248
|
...value.tokenExpiresAt === void 0 ? {} : { tokenExpiresAt: value.tokenExpiresAt },
|
|
40232
40249
|
updatedAt: value.updatedAt
|
|
@@ -40288,11 +40305,7 @@ function credentialError(code, message) {
|
|
|
40288
40305
|
|
|
40289
40306
|
// src/cli/config.ts
|
|
40290
40307
|
var DEFAULT_ENV_FILE = ".env.local";
|
|
40291
|
-
var
|
|
40292
|
-
var ENVIRONMENT_ORIGINS = {
|
|
40293
|
-
production: "https://studio.az8.art",
|
|
40294
|
-
test: "https://studio.az8.studio"
|
|
40295
|
-
};
|
|
40308
|
+
var DEFAULT_BASE_URL = "https://studio.az8.art";
|
|
40296
40309
|
async function resolveCliConfig(options, dependencies) {
|
|
40297
40310
|
const context = await resolveConfigContext(options, dependencies);
|
|
40298
40311
|
const processToken = readToken(context.processEnvironment);
|
|
@@ -40300,7 +40313,7 @@ async function resolveCliConfig(options, dependencies) {
|
|
|
40300
40313
|
if (processToken) {
|
|
40301
40314
|
return {
|
|
40302
40315
|
...context.service,
|
|
40303
|
-
credentials: createExternalCredentialProvider(processToken, "
|
|
40316
|
+
credentials: createExternalCredentialProvider(processToken, "process-env")
|
|
40304
40317
|
};
|
|
40305
40318
|
}
|
|
40306
40319
|
if (fileToken) {
|
|
@@ -40310,10 +40323,10 @@ async function resolveCliConfig(options, dependencies) {
|
|
|
40310
40323
|
};
|
|
40311
40324
|
}
|
|
40312
40325
|
const credentialStore = dependencies.credentialStore ?? new LocalCredentialStore({ env: context.processEnvironment });
|
|
40313
|
-
const localCredential = await credentialStore.read(context.service.
|
|
40326
|
+
const localCredential = await credentialStore.read(context.service.targetKey);
|
|
40314
40327
|
if (!localCredential) {
|
|
40315
40328
|
throw new Error(
|
|
40316
|
-
|
|
40329
|
+
"Missing credentials for the configured AZ8 service. Run az8 login, or provide AZ8_TOKEN through the process environment or an env file."
|
|
40317
40330
|
);
|
|
40318
40331
|
}
|
|
40319
40332
|
let currentCredential = localCredential;
|
|
@@ -40331,8 +40344,9 @@ async function resolveCliConfig(options, dependencies) {
|
|
|
40331
40344
|
async replaceToken(token) {
|
|
40332
40345
|
currentCredential = {
|
|
40333
40346
|
account: currentCredential.account,
|
|
40334
|
-
|
|
40347
|
+
baseUrl: currentCredential.baseUrl,
|
|
40335
40348
|
format: currentCredential.format,
|
|
40349
|
+
targetKey: currentCredential.targetKey,
|
|
40336
40350
|
token: requireSafeToken2(token),
|
|
40337
40351
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
40338
40352
|
};
|
|
@@ -40352,29 +40366,39 @@ async function resolveConfigContext(options, dependencies) {
|
|
|
40352
40366
|
const envFile = options.envFile;
|
|
40353
40367
|
const fileEnvironment = envFile ? await readEnvironmentFile(path4.resolve(cwd, envFile)) : await readDefaultEnvironmentFile(cwd);
|
|
40354
40368
|
const processEnvironment = dependencies.env ?? process.env;
|
|
40355
|
-
const
|
|
40356
|
-
|
|
40369
|
+
const baseUrl = normalizeBaseUrl(
|
|
40370
|
+
processEnvironment.AZ8_BASE_URL ?? fileEnvironment.AZ8_BASE_URL ?? DEFAULT_BASE_URL
|
|
40357
40371
|
);
|
|
40358
|
-
const origin = ENVIRONMENT_ORIGINS[environment];
|
|
40359
40372
|
return {
|
|
40360
40373
|
fileEnvironment,
|
|
40361
40374
|
processEnvironment,
|
|
40362
40375
|
service: {
|
|
40363
|
-
|
|
40364
|
-
|
|
40365
|
-
),
|
|
40366
|
-
environment,
|
|
40376
|
+
baseUrl,
|
|
40377
|
+
backendUrl: `${baseUrl}/api/backend`,
|
|
40367
40378
|
fetch: dependencies.fetch ?? globalThis.fetch,
|
|
40368
|
-
serviceUrl:
|
|
40369
|
-
|
|
40370
|
-
)
|
|
40379
|
+
serviceUrl: `${baseUrl}/api`,
|
|
40380
|
+
targetKey: createTargetKey(baseUrl)
|
|
40371
40381
|
}
|
|
40372
40382
|
};
|
|
40373
40383
|
}
|
|
40374
|
-
function
|
|
40375
|
-
|
|
40376
|
-
|
|
40377
|
-
|
|
40384
|
+
function createTargetKey(baseUrl) {
|
|
40385
|
+
return createHash5("sha256").update(normalizeBaseUrl(baseUrl)).digest("hex");
|
|
40386
|
+
}
|
|
40387
|
+
function normalizeBaseUrl(value) {
|
|
40388
|
+
let url2;
|
|
40389
|
+
try {
|
|
40390
|
+
url2 = new URL(value);
|
|
40391
|
+
} catch {
|
|
40392
|
+
throw new Error("AZ8_BASE_URL must be a valid absolute URL.");
|
|
40393
|
+
}
|
|
40394
|
+
const isLocal = url2.hostname === "localhost" || url2.hostname === "127.0.0.1" || url2.hostname === "::1";
|
|
40395
|
+
if (url2.protocol !== "https:" && !(url2.protocol === "http:" && isLocal)) {
|
|
40396
|
+
throw new Error("AZ8_BASE_URL must use HTTPS, except for localhost development.");
|
|
40397
|
+
}
|
|
40398
|
+
if (url2.username || url2.password || url2.pathname !== "/" || url2.search || url2.hash) {
|
|
40399
|
+
throw new Error("AZ8_BASE_URL must be an origin without credentials, path, query, or fragment.");
|
|
40400
|
+
}
|
|
40401
|
+
return url2.origin;
|
|
40378
40402
|
}
|
|
40379
40403
|
async function readEnvironmentFile(filePath) {
|
|
40380
40404
|
try {
|
|
@@ -40396,18 +40420,15 @@ async function readEnvironmentFile(filePath) {
|
|
|
40396
40420
|
async function readDefaultEnvironmentFile(cwd) {
|
|
40397
40421
|
let directory = path4.resolve(cwd);
|
|
40398
40422
|
while (true) {
|
|
40399
|
-
const
|
|
40400
|
-
if (Object.keys(
|
|
40423
|
+
const values = await readEnvironmentFile(path4.join(directory, DEFAULT_ENV_FILE));
|
|
40424
|
+
if (Object.keys(values).length > 0) return values;
|
|
40401
40425
|
const parent = path4.dirname(directory);
|
|
40402
40426
|
if (parent === directory) return {};
|
|
40403
40427
|
directory = parent;
|
|
40404
40428
|
}
|
|
40405
40429
|
}
|
|
40406
|
-
function
|
|
40407
|
-
|
|
40408
|
-
}
|
|
40409
|
-
function readToken(environment) {
|
|
40410
|
-
const value = environment.AZ8_TOKEN ?? environment.token;
|
|
40430
|
+
function readToken(values) {
|
|
40431
|
+
const value = values.AZ8_TOKEN ?? values.token;
|
|
40411
40432
|
return value ? requireSafeToken2(value) : void 0;
|
|
40412
40433
|
}
|
|
40413
40434
|
function requireSafeToken2(value) {
|
|
@@ -40590,12 +40611,12 @@ async function unlinkIfPresent(filePath) {
|
|
|
40590
40611
|
}
|
|
40591
40612
|
|
|
40592
40613
|
// src/agent-session/state-store.ts
|
|
40593
|
-
import { createHash as
|
|
40614
|
+
import { createHash as createHash6, randomUUID as randomUUID3 } from "node:crypto";
|
|
40594
40615
|
import {
|
|
40595
40616
|
chmod as chmod4,
|
|
40596
40617
|
lstat as lstat4,
|
|
40597
40618
|
mkdir as mkdir3,
|
|
40598
|
-
readdir,
|
|
40619
|
+
readdir as readdir2,
|
|
40599
40620
|
readFile as readFile4,
|
|
40600
40621
|
realpath,
|
|
40601
40622
|
rename as rename3,
|
|
@@ -40606,7 +40627,7 @@ import { homedir as homedir3 } from "node:os";
|
|
|
40606
40627
|
import path5 from "node:path";
|
|
40607
40628
|
|
|
40608
40629
|
// src/agent-session/types.ts
|
|
40609
|
-
var AGENT_SESSION_FORMAT = "az8.agent-session.
|
|
40630
|
+
var AGENT_SESSION_FORMAT = "az8.agent-session.v2";
|
|
40610
40631
|
|
|
40611
40632
|
// src/agent-session/state-store.ts
|
|
40612
40633
|
var SESSION_ID_PATTERN = /^session_[0-9a-f-]{36}$/;
|
|
@@ -40641,7 +40662,7 @@ var AgentSessionStateStore = class {
|
|
|
40641
40662
|
return path5.join(this.descriptorsDirectory(), `${requireSessionId(sessionId)}.json`);
|
|
40642
40663
|
}
|
|
40643
40664
|
socketPath(sessionId) {
|
|
40644
|
-
const digest =
|
|
40665
|
+
const digest = createHash6("sha256").update(requireSessionId(sessionId)).digest("hex").slice(0, 24);
|
|
40645
40666
|
return path5.join(this.runtimeRoot, `${digest}.sock`);
|
|
40646
40667
|
}
|
|
40647
40668
|
async writeDescriptor(descriptor2) {
|
|
@@ -40659,7 +40680,7 @@ var AgentSessionStateStore = class {
|
|
|
40659
40680
|
}
|
|
40660
40681
|
async listDescriptors() {
|
|
40661
40682
|
await this.initialize();
|
|
40662
|
-
const entries = await
|
|
40683
|
+
const entries = await readdir2(this.descriptorsDirectory());
|
|
40663
40684
|
const descriptors = [];
|
|
40664
40685
|
for (const entry of entries.sort()) {
|
|
40665
40686
|
if (!entry.endsWith(".json")) continue;
|
|
@@ -40735,7 +40756,7 @@ var AgentSessionStateStore = class {
|
|
|
40735
40756
|
}
|
|
40736
40757
|
}
|
|
40737
40758
|
contextPath(context) {
|
|
40738
|
-
const digest =
|
|
40759
|
+
const digest = createHash6("sha256").update(context).digest("hex");
|
|
40739
40760
|
return path5.join(this.contextsDirectory(), `${digest}.json`);
|
|
40740
40761
|
}
|
|
40741
40762
|
};
|
|
@@ -40778,7 +40799,7 @@ function assertLaunchSpec(value, launchPath) {
|
|
|
40778
40799
|
if (path5.resolve(value.descriptorPath) !== expectedDescriptor) {
|
|
40779
40800
|
throw sessionStateError("invalid-session-launch", "Session descriptor path is invalid.");
|
|
40780
40801
|
}
|
|
40781
|
-
const socketDigest =
|
|
40802
|
+
const socketDigest = createHash6("sha256").update(sessionId).digest("hex").slice(0, 24);
|
|
40782
40803
|
const expectedSocket = path5.join(
|
|
40783
40804
|
path5.resolve(value.runtimeRoot),
|
|
40784
40805
|
`${socketDigest}.sock`
|
|
@@ -40995,8 +41016,9 @@ async function startAgentSessionDaemon(spec, dependencies = {}) {
|
|
|
40995
41016
|
...await store.readDescriptor(spec.sessionId),
|
|
40996
41017
|
...client.credential ? {
|
|
40997
41018
|
accountId: client.credential.accountId,
|
|
41019
|
+
baseUrl: client.credential.baseUrl,
|
|
40998
41020
|
credentialSource: client.credential.source,
|
|
40999
|
-
|
|
41021
|
+
targetKey: client.credential.targetKey
|
|
41000
41022
|
} : {},
|
|
41001
41023
|
pid: process.pid,
|
|
41002
41024
|
state: "ready"
|
|
@@ -41022,7 +41044,7 @@ async function createCanvasClient(spec, dependencies) {
|
|
|
41022
41044
|
const session = new CanvasSession(config2, spec.projectId, void 0, {
|
|
41023
41045
|
workflowPreferences: (actor) => createNodeWorkflowPreferenceStore({
|
|
41024
41046
|
accountId: actor.accountId,
|
|
41025
|
-
|
|
41047
|
+
targetKey: config2.targetKey,
|
|
41026
41048
|
stateRoot: spec.stateRoot
|
|
41027
41049
|
})
|
|
41028
41050
|
});
|
|
@@ -41033,8 +41055,9 @@ async function createCanvasClient(spec, dependencies) {
|
|
|
41033
41055
|
...config2.credentials.metadata ? {
|
|
41034
41056
|
credential: {
|
|
41035
41057
|
accountId: session.getCollaborationContext().actor.id,
|
|
41036
|
-
|
|
41037
|
-
source: config2.credentials.metadata.source
|
|
41058
|
+
baseUrl: config2.baseUrl,
|
|
41059
|
+
source: config2.credentials.metadata.source,
|
|
41060
|
+
targetKey: config2.targetKey
|
|
41038
41061
|
}
|
|
41039
41062
|
} : {},
|
|
41040
41063
|
executeOperation: (input) => client.executeOperation(input),
|
|
@@ -41053,7 +41076,6 @@ function openingDescriptor(spec, pid) {
|
|
|
41053
41076
|
return {
|
|
41054
41077
|
clientName: spec.clientName,
|
|
41055
41078
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
41056
|
-
...spec.config.environment || spec.config.env ? { environment: spec.config.environment ?? spec.config.env } : {},
|
|
41057
41079
|
format: AGENT_SESSION_FORMAT,
|
|
41058
41080
|
pid,
|
|
41059
41081
|
projectId: spec.projectId,
|
|
@@ -41115,6 +41137,131 @@ function readErrorCode2(error51) {
|
|
|
41115
41137
|
return typeof error51 === "object" && error51 !== null && "code" in error51 ? String(error51.code) : "session-daemon-failed";
|
|
41116
41138
|
}
|
|
41117
41139
|
|
|
41140
|
+
// src/auth/browser-authorization.ts
|
|
41141
|
+
import { spawn } from "node:child_process";
|
|
41142
|
+
import { createHash as createHash7, randomBytes } from "node:crypto";
|
|
41143
|
+
async function runBrowserAuthorization(config2, options, dependencies = {}) {
|
|
41144
|
+
const platform = dependencies.platform ?? process.platform;
|
|
41145
|
+
if (!["darwin", "linux", "win32"].includes(platform)) {
|
|
41146
|
+
throw authorizationError(
|
|
41147
|
+
"unsupported-login-platform",
|
|
41148
|
+
`Browser login is not supported on ${platform}.`
|
|
41149
|
+
);
|
|
41150
|
+
}
|
|
41151
|
+
const pair = createPkcePair();
|
|
41152
|
+
const created = await createCliAuthorization(config2, {
|
|
41153
|
+
clientName: options.clientName,
|
|
41154
|
+
clientVersion: options.clientVersion,
|
|
41155
|
+
codeChallenge: pair.challenge,
|
|
41156
|
+
platform
|
|
41157
|
+
});
|
|
41158
|
+
if (new URL(created.verification_uri).origin !== config2.baseUrl || new URL(created.verification_uri_complete).origin !== config2.baseUrl) {
|
|
41159
|
+
throw authorizationError(
|
|
41160
|
+
"authorization-service-mismatch",
|
|
41161
|
+
"Account service created the authorization for a different AZ8 service."
|
|
41162
|
+
);
|
|
41163
|
+
}
|
|
41164
|
+
let browserOpened = false;
|
|
41165
|
+
if (!options.noOpen && dependencies.openUrl) {
|
|
41166
|
+
try {
|
|
41167
|
+
await dependencies.openUrl(created.verification_uri_complete);
|
|
41168
|
+
browserOpened = true;
|
|
41169
|
+
} catch {
|
|
41170
|
+
browserOpened = false;
|
|
41171
|
+
}
|
|
41172
|
+
}
|
|
41173
|
+
dependencies.onProgress?.({
|
|
41174
|
+
baseUrl: config2.baseUrl,
|
|
41175
|
+
browserOpened,
|
|
41176
|
+
expiresAt: created.expires_at,
|
|
41177
|
+
format: "az8.auth.login-progress.v2",
|
|
41178
|
+
status: "verification_required",
|
|
41179
|
+
userCode: created.user_code,
|
|
41180
|
+
verificationUriComplete: created.verification_uri_complete
|
|
41181
|
+
});
|
|
41182
|
+
const now = dependencies.now ?? Date.now;
|
|
41183
|
+
const sleep = dependencies.sleep ?? abortableSleep;
|
|
41184
|
+
let interval = created.interval;
|
|
41185
|
+
while (Math.floor(now() / 1e3) < created.expires_at) {
|
|
41186
|
+
await sleep(interval * 1e3, dependencies.signal);
|
|
41187
|
+
assertNotAborted(dependencies.signal);
|
|
41188
|
+
const exchange = await exchangeCliAuthorization(config2, {
|
|
41189
|
+
codeVerifier: pair.verifier,
|
|
41190
|
+
deviceCode: created.device_code
|
|
41191
|
+
});
|
|
41192
|
+
if (exchange.status === "completed") {
|
|
41193
|
+
return {
|
|
41194
|
+
token: exchange.token,
|
|
41195
|
+
tokenExpiresAt: exchange.token_expires_at
|
|
41196
|
+
};
|
|
41197
|
+
}
|
|
41198
|
+
if (exchange.status === "access_denied") {
|
|
41199
|
+
throw authorizationError("authorization-denied", "Browser authorization was denied.");
|
|
41200
|
+
}
|
|
41201
|
+
if (exchange.status === "expired_token") {
|
|
41202
|
+
throw authorizationError(
|
|
41203
|
+
"authorization-expired",
|
|
41204
|
+
"Browser authorization expired or was already consumed. Start a new login attempt."
|
|
41205
|
+
);
|
|
41206
|
+
}
|
|
41207
|
+
interval = exchange.interval;
|
|
41208
|
+
dependencies.onProgress?.({
|
|
41209
|
+
baseUrl: config2.baseUrl,
|
|
41210
|
+
expiresAt: exchange.expires_at,
|
|
41211
|
+
format: "az8.auth.login-progress.v2",
|
|
41212
|
+
interval,
|
|
41213
|
+
status: exchange.status
|
|
41214
|
+
});
|
|
41215
|
+
}
|
|
41216
|
+
throw authorizationError(
|
|
41217
|
+
"authorization-expired",
|
|
41218
|
+
"Browser authorization expired. Start a new login attempt."
|
|
41219
|
+
);
|
|
41220
|
+
}
|
|
41221
|
+
function createPkcePair() {
|
|
41222
|
+
const verifier = randomBytes(32).toString("base64url");
|
|
41223
|
+
return {
|
|
41224
|
+
challenge: createHash7("sha256").update(verifier).digest("base64url"),
|
|
41225
|
+
verifier
|
|
41226
|
+
};
|
|
41227
|
+
}
|
|
41228
|
+
async function openSystemBrowser(url2) {
|
|
41229
|
+
const [command, args2] = process.platform === "darwin" ? ["open", [url2]] : process.platform === "win32" ? ["rundll32", ["url.dll,FileProtocolHandler", url2]] : ["xdg-open", [url2]];
|
|
41230
|
+
await new Promise((resolve, reject) => {
|
|
41231
|
+
const child = spawn(command, args2, { detached: true, stdio: "ignore" });
|
|
41232
|
+
child.once("error", reject);
|
|
41233
|
+
child.once("spawn", () => {
|
|
41234
|
+
child.unref();
|
|
41235
|
+
resolve();
|
|
41236
|
+
});
|
|
41237
|
+
});
|
|
41238
|
+
}
|
|
41239
|
+
function abortableSleep(milliseconds, signal) {
|
|
41240
|
+
return new Promise((resolve, reject) => {
|
|
41241
|
+
if (signal?.aborted) {
|
|
41242
|
+
reject(authorizationError("login-cancelled", "Browser login was cancelled."));
|
|
41243
|
+
return;
|
|
41244
|
+
}
|
|
41245
|
+
const handleAbort = () => {
|
|
41246
|
+
clearTimeout(timer);
|
|
41247
|
+
reject(authorizationError("login-cancelled", "Browser login was cancelled."));
|
|
41248
|
+
};
|
|
41249
|
+
const timer = setTimeout(() => {
|
|
41250
|
+
signal?.removeEventListener("abort", handleAbort);
|
|
41251
|
+
resolve();
|
|
41252
|
+
}, milliseconds);
|
|
41253
|
+
signal?.addEventListener("abort", handleAbort, { once: true });
|
|
41254
|
+
});
|
|
41255
|
+
}
|
|
41256
|
+
function assertNotAborted(signal) {
|
|
41257
|
+
if (signal?.aborted) {
|
|
41258
|
+
throw authorizationError("login-cancelled", "Browser login was cancelled.");
|
|
41259
|
+
}
|
|
41260
|
+
}
|
|
41261
|
+
function authorizationError(code, message) {
|
|
41262
|
+
return Object.assign(new Error(message), { code });
|
|
41263
|
+
}
|
|
41264
|
+
|
|
41118
41265
|
// src/canvas/protocol.ts
|
|
41119
41266
|
var AZ8_PROTOCOL_VERSION = "1.1";
|
|
41120
41267
|
var ProtocolInputError = class extends Error {
|
|
@@ -45249,7 +45396,7 @@ function formatZodError(error51) {
|
|
|
45249
45396
|
}
|
|
45250
45397
|
|
|
45251
45398
|
// src/media/download.ts
|
|
45252
|
-
import { createHash as
|
|
45399
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
45253
45400
|
import { link, lstat as lstat5, open as open2, rename as rename4, stat, unlink as unlink4 } from "node:fs/promises";
|
|
45254
45401
|
import path8 from "node:path";
|
|
45255
45402
|
|
|
@@ -45699,7 +45846,7 @@ async function streamResponseToFile(response, handle, deadline, expectedBytes) {
|
|
|
45699
45846
|
);
|
|
45700
45847
|
}
|
|
45701
45848
|
const reader = response.body.getReader();
|
|
45702
|
-
const hash2 =
|
|
45849
|
+
const hash2 = createHash8("sha256");
|
|
45703
45850
|
let bytes = 0;
|
|
45704
45851
|
try {
|
|
45705
45852
|
while (true) {
|
|
@@ -45943,10 +46090,10 @@ async function waitForDownloadRetry(delayMs, deadlineAt, dependencies) {
|
|
|
45943
46090
|
phase: "retry-wait"
|
|
45944
46091
|
});
|
|
45945
46092
|
}
|
|
45946
|
-
await (dependencies.sleep ??
|
|
46093
|
+
await (dependencies.sleep ?? abortableSleep2)(delayMs, dependencies.signal);
|
|
45947
46094
|
throwIfCancelled(dependencies.signal);
|
|
45948
46095
|
}
|
|
45949
|
-
async function
|
|
46096
|
+
async function abortableSleep2(delayMs, signal) {
|
|
45950
46097
|
if (signal?.aborted) return;
|
|
45951
46098
|
await new Promise((resolve) => {
|
|
45952
46099
|
const timeout = setTimeout(done, delayMs);
|
|
@@ -46056,7 +46203,7 @@ function canvasOneShotSetupError(kind, projectId, capability, error51) {
|
|
|
46056
46203
|
}
|
|
46057
46204
|
|
|
46058
46205
|
// src/agent-session/manager.ts
|
|
46059
|
-
import { spawn } from "node:child_process";
|
|
46206
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
46060
46207
|
import path9 from "node:path";
|
|
46061
46208
|
var AgentSessionManager = class {
|
|
46062
46209
|
constructor(options = {}) {
|
|
@@ -46064,7 +46211,7 @@ var AgentSessionManager = class {
|
|
|
46064
46211
|
this.store = options.stateStore ?? new AgentSessionStateStore({ cwd: options.cwd, env: options.env });
|
|
46065
46212
|
this.entrypoint = options.entrypoint ?? process.argv[1] ?? "";
|
|
46066
46213
|
this.requestImplementation = options.request ?? requestAgentSession;
|
|
46067
|
-
this.spawnProcess = options.spawnProcess ?? ((command, args2, spawnOptions) =>
|
|
46214
|
+
this.spawnProcess = options.spawnProcess ?? ((command, args2, spawnOptions) => spawn2(command, args2, spawnOptions));
|
|
46068
46215
|
}
|
|
46069
46216
|
options;
|
|
46070
46217
|
store;
|
|
@@ -46090,7 +46237,6 @@ var AgentSessionManager = class {
|
|
|
46090
46237
|
const descriptor2 = {
|
|
46091
46238
|
clientName,
|
|
46092
46239
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
46093
|
-
...config2.environment || config2.env ? { environment: config2.environment ?? config2.env } : {},
|
|
46094
46240
|
format: AGENT_SESSION_FORMAT,
|
|
46095
46241
|
pid: 0,
|
|
46096
46242
|
projectId: input.projectId,
|
|
@@ -46262,7 +46408,7 @@ var AgentSessionManager = class {
|
|
|
46262
46408
|
}
|
|
46263
46409
|
async closeLocalCredentialSessions(input) {
|
|
46264
46410
|
const descriptors = (await this.store.listDescriptors()).filter(
|
|
46265
|
-
(descriptor2) => descriptor2.credentialSource === "local" && descriptor2.
|
|
46411
|
+
(descriptor2) => descriptor2.credentialSource === "local" && descriptor2.targetKey === input.targetKey
|
|
46266
46412
|
);
|
|
46267
46413
|
const closed = [];
|
|
46268
46414
|
for (const descriptor2 of descriptors) {
|
|
@@ -46346,143 +46492,16 @@ function managerError(code, message) {
|
|
|
46346
46492
|
return Object.assign(new Error(message), { code });
|
|
46347
46493
|
}
|
|
46348
46494
|
|
|
46349
|
-
// src/auth/browser-authorization.ts
|
|
46350
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
46351
|
-
import { createHash as createHash6, randomBytes } from "node:crypto";
|
|
46352
|
-
async function runBrowserAuthorization(config2, options, dependencies = {}) {
|
|
46353
|
-
const platform = dependencies.platform ?? process.platform;
|
|
46354
|
-
if (!["darwin", "linux", "win32"].includes(platform)) {
|
|
46355
|
-
throw authorizationError(
|
|
46356
|
-
"unsupported-login-platform",
|
|
46357
|
-
`Browser login is not supported on ${platform}.`
|
|
46358
|
-
);
|
|
46359
|
-
}
|
|
46360
|
-
const pair = createPkcePair();
|
|
46361
|
-
const created = await createCliAuthorization(config2, {
|
|
46362
|
-
clientName: options.clientName,
|
|
46363
|
-
clientVersion: options.clientVersion,
|
|
46364
|
-
codeChallenge: pair.challenge,
|
|
46365
|
-
platform
|
|
46366
|
-
});
|
|
46367
|
-
if (created.environment !== config2.environment) {
|
|
46368
|
-
throw authorizationError(
|
|
46369
|
-
"authorization-environment-mismatch",
|
|
46370
|
-
"Account service created the authorization in a different environment."
|
|
46371
|
-
);
|
|
46372
|
-
}
|
|
46373
|
-
let browserOpened = false;
|
|
46374
|
-
if (!options.noOpen) {
|
|
46375
|
-
try {
|
|
46376
|
-
await (dependencies.openUrl ?? openBrowser)(created.verification_uri_complete);
|
|
46377
|
-
browserOpened = true;
|
|
46378
|
-
} catch {
|
|
46379
|
-
browserOpened = false;
|
|
46380
|
-
}
|
|
46381
|
-
}
|
|
46382
|
-
dependencies.onProgress?.({
|
|
46383
|
-
browserOpened,
|
|
46384
|
-
environment: config2.environment,
|
|
46385
|
-
expiresAt: created.expires_at,
|
|
46386
|
-
format: "az8.auth.login-progress.v1",
|
|
46387
|
-
status: "verification_required",
|
|
46388
|
-
userCode: created.user_code,
|
|
46389
|
-
verificationUriComplete: created.verification_uri_complete
|
|
46390
|
-
});
|
|
46391
|
-
const now = dependencies.now ?? Date.now;
|
|
46392
|
-
const sleep = dependencies.sleep ?? abortableSleep2;
|
|
46393
|
-
let interval = created.interval;
|
|
46394
|
-
while (Math.floor(now() / 1e3) < created.expires_at) {
|
|
46395
|
-
await sleep(interval * 1e3, dependencies.signal);
|
|
46396
|
-
assertNotAborted(dependencies.signal);
|
|
46397
|
-
const exchange = await exchangeCliAuthorization(config2, {
|
|
46398
|
-
codeVerifier: pair.verifier,
|
|
46399
|
-
deviceCode: created.device_code
|
|
46400
|
-
});
|
|
46401
|
-
if (exchange.status === "completed") {
|
|
46402
|
-
return {
|
|
46403
|
-
token: exchange.token,
|
|
46404
|
-
tokenExpiresAt: exchange.token_expires_at
|
|
46405
|
-
};
|
|
46406
|
-
}
|
|
46407
|
-
if (exchange.status === "access_denied") {
|
|
46408
|
-
throw authorizationError("authorization-denied", "Browser authorization was denied.");
|
|
46409
|
-
}
|
|
46410
|
-
if (exchange.status === "expired_token") {
|
|
46411
|
-
throw authorizationError(
|
|
46412
|
-
"authorization-expired",
|
|
46413
|
-
"Browser authorization expired or was already consumed. Start a new login attempt."
|
|
46414
|
-
);
|
|
46415
|
-
}
|
|
46416
|
-
interval = exchange.interval;
|
|
46417
|
-
dependencies.onProgress?.({
|
|
46418
|
-
environment: config2.environment,
|
|
46419
|
-
expiresAt: exchange.expires_at,
|
|
46420
|
-
format: "az8.auth.login-progress.v1",
|
|
46421
|
-
interval,
|
|
46422
|
-
status: exchange.status
|
|
46423
|
-
});
|
|
46424
|
-
}
|
|
46425
|
-
throw authorizationError(
|
|
46426
|
-
"authorization-expired",
|
|
46427
|
-
"Browser authorization expired. Start a new login attempt."
|
|
46428
|
-
);
|
|
46429
|
-
}
|
|
46430
|
-
function createPkcePair() {
|
|
46431
|
-
const verifier = randomBytes(32).toString("base64url");
|
|
46432
|
-
return {
|
|
46433
|
-
challenge: createHash6("sha256").update(verifier).digest("base64url"),
|
|
46434
|
-
verifier
|
|
46435
|
-
};
|
|
46436
|
-
}
|
|
46437
|
-
async function openBrowser(url2) {
|
|
46438
|
-
const [command, args2] = process.platform === "darwin" ? ["open", [url2]] : process.platform === "win32" ? ["rundll32", ["url.dll,FileProtocolHandler", url2]] : ["xdg-open", [url2]];
|
|
46439
|
-
await new Promise((resolve, reject) => {
|
|
46440
|
-
const child = spawn2(command, args2, { detached: true, stdio: "ignore" });
|
|
46441
|
-
child.once("error", reject);
|
|
46442
|
-
child.once("spawn", () => {
|
|
46443
|
-
child.unref();
|
|
46444
|
-
resolve();
|
|
46445
|
-
});
|
|
46446
|
-
});
|
|
46447
|
-
}
|
|
46448
|
-
function abortableSleep2(milliseconds, signal) {
|
|
46449
|
-
return new Promise((resolve, reject) => {
|
|
46450
|
-
if (signal?.aborted) {
|
|
46451
|
-
reject(authorizationError("login-cancelled", "Browser login was cancelled."));
|
|
46452
|
-
return;
|
|
46453
|
-
}
|
|
46454
|
-
const handleAbort = () => {
|
|
46455
|
-
clearTimeout(timer);
|
|
46456
|
-
reject(authorizationError("login-cancelled", "Browser login was cancelled."));
|
|
46457
|
-
};
|
|
46458
|
-
const timer = setTimeout(() => {
|
|
46459
|
-
signal?.removeEventListener("abort", handleAbort);
|
|
46460
|
-
resolve();
|
|
46461
|
-
}, milliseconds);
|
|
46462
|
-
signal?.addEventListener("abort", handleAbort, { once: true });
|
|
46463
|
-
});
|
|
46464
|
-
}
|
|
46465
|
-
function assertNotAborted(signal) {
|
|
46466
|
-
if (signal?.aborted) {
|
|
46467
|
-
throw authorizationError("login-cancelled", "Browser login was cancelled.");
|
|
46468
|
-
}
|
|
46469
|
-
}
|
|
46470
|
-
function authorizationError(code, message) {
|
|
46471
|
-
return Object.assign(new Error(message), { code });
|
|
46472
|
-
}
|
|
46473
|
-
|
|
46474
46495
|
// package.json
|
|
46475
46496
|
var package_default = {
|
|
46476
46497
|
name: "@everfir/az8-cli",
|
|
46477
|
-
version: "0.
|
|
46498
|
+
version: "0.5.0",
|
|
46478
46499
|
description: "Semantic Project Canvas client for AZ8 Studio agents.",
|
|
46479
46500
|
license: "UNLICENSED",
|
|
46480
46501
|
type: "module",
|
|
46481
46502
|
files: [
|
|
46482
46503
|
"dist",
|
|
46483
|
-
"skills"
|
|
46484
|
-
"CHANGELOG.md",
|
|
46485
|
-
"RELEASE.md"
|
|
46504
|
+
"skills"
|
|
46486
46505
|
],
|
|
46487
46506
|
bin: {
|
|
46488
46507
|
az8: "dist/main.js"
|
|
@@ -46546,13 +46565,7 @@ var optionalPositiveInteger = (name) => external_exports.string().regex(/^\d+$/,
|
|
|
46546
46565
|
var optionalWorkflowCatalogPageSize = external_exports.string().regex(/^\d+$/, "--page-size must be an integer.").transform(Number).refine((value) => value >= 1 && value <= 50, "--page-size must be between 1 and 50.").optional();
|
|
46547
46566
|
var optionalFiniteNumber = (name) => external_exports.string().transform(Number).refine(Number.isFinite, `${name} must be finite.`).optional();
|
|
46548
46567
|
var configOptionsSchema = external_exports.object({
|
|
46549
|
-
|
|
46550
|
-
env: external_exports.enum(["test", "production"], { error: "--env must be test or production." }).optional(),
|
|
46551
|
-
envFile: external_exports.string().optional(),
|
|
46552
|
-
environment: external_exports.enum(["test", "production"], {
|
|
46553
|
-
error: "--environment must be test or production."
|
|
46554
|
-
}).optional(),
|
|
46555
|
-
serviceUrl: external_exports.string().optional()
|
|
46568
|
+
envFile: external_exports.string().optional()
|
|
46556
46569
|
});
|
|
46557
46570
|
var guideOptionsSchema = external_exports.object({
|
|
46558
46571
|
format: external_exports.enum(["markdown", "json"], { error: "Unknown guide format. Expected markdown or json." }).default("markdown"),
|
|
@@ -46668,11 +46681,7 @@ var agentSessionInputOptionsSchema = inputSourceOptionsSchema.and(
|
|
|
46668
46681
|
function readConfigOptions(command) {
|
|
46669
46682
|
const options = command.optsWithGlobals();
|
|
46670
46683
|
return parseCliOptions(configOptionsSchema, {
|
|
46671
|
-
|
|
46672
|
-
env: options.env,
|
|
46673
|
-
envFile: options.envFile,
|
|
46674
|
-
environment: options.environment,
|
|
46675
|
-
serviceUrl: options.serviceUrl
|
|
46684
|
+
envFile: options.envFile
|
|
46676
46685
|
});
|
|
46677
46686
|
}
|
|
46678
46687
|
|
|
@@ -46714,17 +46723,18 @@ function registerAuthCommands(program2, dependencies, setResult) {
|
|
|
46714
46723
|
}
|
|
46715
46724
|
});
|
|
46716
46725
|
const store = createLocalCredentialStore(dependencies);
|
|
46717
|
-
const previous = await store.read(service.
|
|
46726
|
+
const previous = await store.read(service.targetKey);
|
|
46718
46727
|
const account = storedAccount(profile);
|
|
46719
46728
|
let closedSessions = 0;
|
|
46720
46729
|
if (!previous || previous.account.accountId !== account.accountId) {
|
|
46721
46730
|
const manager = dependencies.sessionManager ?? new AgentSessionManager({ cwd: dependencies.cwd, env: dependencies.env });
|
|
46722
|
-
closedSessions = (await manager.closeLocalCredentialSessions({
|
|
46731
|
+
closedSessions = (await manager.closeLocalCredentialSessions({ targetKey: service.targetKey })).length;
|
|
46723
46732
|
}
|
|
46724
46733
|
await store.write({
|
|
46725
46734
|
account,
|
|
46726
|
-
|
|
46735
|
+
baseUrl: service.baseUrl,
|
|
46727
46736
|
format: LOCAL_CREDENTIAL_FORMAT,
|
|
46737
|
+
targetKey: service.targetKey,
|
|
46728
46738
|
token: issuedToken,
|
|
46729
46739
|
...issuedTokenExpiresAt === void 0 ? {} : { tokenExpiresAt: issuedTokenExpiresAt },
|
|
46730
46740
|
updatedAt: new Date((dependencies.now ?? Date.now)()).toISOString()
|
|
@@ -46738,9 +46748,9 @@ function registerAuthCommands(program2, dependencies, setResult) {
|
|
|
46738
46748
|
persisted: true,
|
|
46739
46749
|
source: "local"
|
|
46740
46750
|
},
|
|
46741
|
-
|
|
46742
|
-
format: "az8.auth.login.v1",
|
|
46751
|
+
format: "az8.auth.login.v2",
|
|
46743
46752
|
operation: "login",
|
|
46753
|
+
service: { baseUrl: service.baseUrl },
|
|
46744
46754
|
sessionsClosed: closedSessions
|
|
46745
46755
|
})
|
|
46746
46756
|
);
|
|
@@ -46762,37 +46772,44 @@ function registerAuthCommands(program2, dependencies, setResult) {
|
|
|
46762
46772
|
persisted: config2.credentials.metadata?.persisted ?? false,
|
|
46763
46773
|
source: config2.credentials.metadata?.source ?? "unknown"
|
|
46764
46774
|
},
|
|
46765
|
-
|
|
46766
|
-
|
|
46767
|
-
|
|
46775
|
+
format: "az8.auth.whoami.v2",
|
|
46776
|
+
operation: "whoami",
|
|
46777
|
+
service: { baseUrl: config2.baseUrl }
|
|
46768
46778
|
})
|
|
46769
46779
|
);
|
|
46770
46780
|
} catch (error51) {
|
|
46771
46781
|
setResult(errorResult(safeErrorMessage(error51)));
|
|
46772
46782
|
}
|
|
46773
46783
|
});
|
|
46774
|
-
program2.command("logout").description("Remove locally stored account credentials").option("--all", "Remove
|
|
46784
|
+
program2.command("logout").description("Remove locally stored account credentials").option("--all", "Remove all locally stored account credentials").action(async (rawOptions, command) => {
|
|
46775
46785
|
try {
|
|
46776
46786
|
const options = parseCliOptions(logoutOptionsSchema, rawOptions);
|
|
46777
46787
|
const configOptions = readConfigOptions(command);
|
|
46778
|
-
const selected =
|
|
46779
|
-
const environments = options.all ? ["test", "production"] : [selected];
|
|
46788
|
+
const selected = await resolveCliServiceConfig(configOptions, dependencies);
|
|
46780
46789
|
const store = createLocalCredentialStore(dependencies);
|
|
46781
46790
|
const manager = dependencies.sessionManager ?? new AgentSessionManager({ cwd: dependencies.cwd, env: dependencies.env });
|
|
46791
|
+
const targets = options.all ? await store.list() : [
|
|
46792
|
+
{
|
|
46793
|
+
baseUrl: selected.baseUrl,
|
|
46794
|
+
targetKey: selected.targetKey
|
|
46795
|
+
}
|
|
46796
|
+
];
|
|
46782
46797
|
const results = [];
|
|
46783
|
-
for (const
|
|
46784
|
-
const sessions = await manager.closeLocalCredentialSessions({
|
|
46798
|
+
for (const target of targets) {
|
|
46799
|
+
const sessions = await manager.closeLocalCredentialSessions({
|
|
46800
|
+
targetKey: target.targetKey
|
|
46801
|
+
});
|
|
46785
46802
|
results.push({
|
|
46786
|
-
|
|
46787
|
-
|
|
46803
|
+
removed: await store.delete(target.targetKey),
|
|
46804
|
+
service: { baseUrl: target.baseUrl },
|
|
46788
46805
|
sessionsClosed: sessions.length
|
|
46789
46806
|
});
|
|
46790
46807
|
}
|
|
46791
46808
|
setResult(
|
|
46792
46809
|
jsonResult({
|
|
46793
|
-
|
|
46794
|
-
|
|
46795
|
-
|
|
46810
|
+
format: "az8.auth.logout.v2",
|
|
46811
|
+
operation: "logout",
|
|
46812
|
+
targets: results
|
|
46796
46813
|
})
|
|
46797
46814
|
);
|
|
46798
46815
|
} catch (error51) {
|
|
@@ -46802,7 +46819,7 @@ function registerAuthCommands(program2, dependencies, setResult) {
|
|
|
46802
46819
|
}
|
|
46803
46820
|
async function updateStoredProfile(config2, profile, dependencies) {
|
|
46804
46821
|
const store = createLocalCredentialStore(dependencies);
|
|
46805
|
-
const current = await store.read(config2.
|
|
46822
|
+
const current = await store.read(config2.targetKey);
|
|
46806
46823
|
if (!current) return;
|
|
46807
46824
|
const next = {
|
|
46808
46825
|
...current,
|
|
@@ -47478,7 +47495,7 @@ function readSessionOption(command) {
|
|
|
47478
47495
|
}
|
|
47479
47496
|
function sessionDocument(operation, descriptor2) {
|
|
47480
47497
|
return {
|
|
47481
|
-
format: "az8.agent-session.lifecycle.
|
|
47498
|
+
format: "az8.agent-session.lifecycle.v2",
|
|
47482
47499
|
operation,
|
|
47483
47500
|
session: publicDescriptor(descriptor2)
|
|
47484
47501
|
};
|
|
@@ -47487,11 +47504,11 @@ function publicDescriptor(descriptor2) {
|
|
|
47487
47504
|
return {
|
|
47488
47505
|
clientName: descriptor2.clientName,
|
|
47489
47506
|
createdAt: descriptor2.createdAt,
|
|
47490
|
-
...descriptor2.environment ? { environment: descriptor2.environment } : {},
|
|
47491
47507
|
...descriptor2.error ? { error: descriptor2.error } : {},
|
|
47492
47508
|
pid: descriptor2.pid,
|
|
47493
47509
|
projectId: descriptor2.projectId,
|
|
47494
47510
|
sessionId: descriptor2.sessionId,
|
|
47511
|
+
...descriptor2.baseUrl ? { service: { baseUrl: descriptor2.baseUrl } } : {},
|
|
47495
47512
|
state: descriptor2.state
|
|
47496
47513
|
};
|
|
47497
47514
|
}
|
|
@@ -47571,12 +47588,7 @@ function findCommand(program2, commandNames) {
|
|
|
47571
47588
|
return current;
|
|
47572
47589
|
}
|
|
47573
47590
|
function addCommonOptions(program2) {
|
|
47574
|
-
program2.
|
|
47575
|
-
new Option(
|
|
47576
|
-
"--environment <environment>",
|
|
47577
|
-
"Select test or production API environment"
|
|
47578
|
-
).helpGroup("Global options:")
|
|
47579
|
-
).addOption(new Option("--env <environment>", "Alias for --environment").hideHelp()).option("--backend-url <url>", "Override the backend API base URL").option("--service-url <url>", "Override the account service API base URL").option("--env-file <path>", "Load credentials and environment from a file");
|
|
47591
|
+
program2.option("--env-file <path>", "Load credentials from a file");
|
|
47580
47592
|
}
|
|
47581
47593
|
|
|
47582
47594
|
// src/cli/run.ts
|
|
@@ -47634,6 +47646,7 @@ process.once("SIGINT", abortOnSignal);
|
|
|
47634
47646
|
process.once("SIGTERM", abortOnSignal);
|
|
47635
47647
|
try {
|
|
47636
47648
|
const result3 = await runAz8Cli(process.argv.slice(2), {
|
|
47649
|
+
openUrl: openSystemBrowser,
|
|
47637
47650
|
onAuthProgress(progress) {
|
|
47638
47651
|
process.stderr.write(`${JSON.stringify(progress)}
|
|
47639
47652
|
`);
|