@zleap-ai/sag-cli 0.6.0 → 0.6.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.
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@ import { checkbox, confirm, input, select } from "@inquirer/prompts";
9
9
  // package.json
10
10
  var package_default = {
11
11
  name: "@zleap-ai/sag-cli",
12
- version: "0.6.0",
12
+ version: "0.6.1",
13
13
  description: "Command-line client and diagnostics for SAG knowledge bases",
14
14
  type: "module",
15
15
  bin: {
@@ -2851,10 +2851,15 @@ var skillAccountSchema = z11.strictObject({
2851
2851
  user: z11.strictObject({ id: z11.string().min(1), name: z11.string().min(1) }),
2852
2852
  recentKnowledgeBase: recentKnowledgeBaseSchema.optional()
2853
2853
  });
2854
+ var skillLinkTokenSchema = z11.strictObject({
2855
+ kind: z11.literal("open_link"),
2856
+ token: z11.string().regex(/^zmp_[A-Za-z0-9_-]{32,}$/)
2857
+ });
2858
+ var skillAuthorizationSchema = z11.union([skillAccountSchema, skillLinkTokenSchema]);
2854
2859
  var skillAccountConfigSchema = z11.object({
2855
2860
  version: z11.literal(1),
2856
2861
  currentOrigin: z11.string().optional(),
2857
- accounts: z11.record(z11.string(), skillAccountSchema)
2862
+ accounts: z11.record(z11.string(), skillAuthorizationSchema)
2858
2863
  }).passthrough();
2859
2864
  function configurationConflict(message, filePath) {
2860
2865
  return new CliError("CONFIG_CONFLICT", message, {
@@ -2912,6 +2917,21 @@ var SkillAccountConfigStore = class {
2912
2917
  await this.#saveUnlocked(config);
2913
2918
  });
2914
2919
  }
2920
+ async saveLinkToken(origin, token) {
2921
+ const normalizedOrigin = normalizeSkillOrigin(origin);
2922
+ let authorization;
2923
+ try {
2924
+ authorization = skillLinkTokenSchema.parse({ kind: "open_link", token });
2925
+ } catch {
2926
+ throw configurationConflict("Open Link token is invalid", this.filePath);
2927
+ }
2928
+ await this.#withLock(async () => {
2929
+ const config = await this.load();
2930
+ config.accounts[normalizedOrigin] = authorization;
2931
+ config.currentOrigin = normalizedOrigin;
2932
+ await this.#saveUnlocked(config);
2933
+ });
2934
+ }
2915
2935
  async removeAccount(origin) {
2916
2936
  const normalizedOrigin = normalizeSkillOrigin(origin);
2917
2937
  await this.#withLock(async () => {
@@ -2932,6 +2952,10 @@ var SkillAccountConfigStore = class {
2932
2952
  });
2933
2953
  }
2934
2954
  async getAccount(origin) {
2955
+ const authorization = (await this.load()).accounts[normalizeSkillOrigin(origin)];
2956
+ return authorization && !("kind" in authorization) ? authorization : null;
2957
+ }
2958
+ async getAuthorization(origin) {
2935
2959
  return (await this.load()).accounts[normalizeSkillOrigin(origin)] ?? null;
2936
2960
  }
2937
2961
  async saveRecentKnowledgeBase(origin, knowledgeBase) {
@@ -2946,6 +2970,7 @@ var SkillAccountConfigStore = class {
2946
2970
  this.filePath
2947
2971
  );
2948
2972
  }
2973
+ if ("kind" in account) return;
2949
2974
  config.accounts[normalizedOrigin] = {
2950
2975
  ...account,
2951
2976
  recentKnowledgeBase: validated
@@ -7431,8 +7456,19 @@ async function withFreshSkillAccount(runtime2, origin, operation) {
7431
7456
  );
7432
7457
  return operation(accessToken);
7433
7458
  }
7459
+ async function withSkillAuthorization(runtime2, origin, operation) {
7460
+ const normalizedOrigin = normalizeSkillOrigin(origin);
7461
+ const authorization = runtime2.config.getAuthorization ? await runtime2.config.getAuthorization(normalizedOrigin) : null;
7462
+ if (authorization && "kind" in authorization) return operation(authorization.token);
7463
+ return withFreshSkillAccount(runtime2, normalizedOrigin, operation);
7464
+ }
7434
7465
  async function logoutSkillAccount(runtime2, origin) {
7435
7466
  const normalizedOrigin = normalizeSkillOrigin(origin);
7467
+ const authorization = runtime2.config.getAuthorization ? await runtime2.config.getAuthorization(normalizedOrigin) : null;
7468
+ if (authorization && "kind" in authorization) {
7469
+ await runtime2.config.removeAccount(normalizedOrigin);
7470
+ return true;
7471
+ }
7436
7472
  const account = await runtime2.config.getAccount(normalizedOrigin);
7437
7473
  if (!account) return false;
7438
7474
  await runtime2.client.logout(
@@ -7588,7 +7624,7 @@ async function remember(runtime2, origin, knowledgeBase) {
7588
7624
  }
7589
7625
  async function withSkillAccountKnowledgeClient(runtime2, origin, operation) {
7590
7626
  const normalizedOrigin = normalizeSkillOrigin(origin);
7591
- return withFreshSkillAccount(
7627
+ return withSkillAuthorization(
7592
7628
  runtime2.auth,
7593
7629
  normalizedOrigin,
7594
7630
  (accessToken) => operation(runtime2.createClient({ accessToken, origin: normalizedOrigin }))
@@ -7812,6 +7848,16 @@ function httpError(status2, problemCode, problemData) {
7812
7848
  ...details
7813
7849
  });
7814
7850
  }
7851
+ if (normalizedProblemCode === "open_link_token_invalid") {
7852
+ return new SkillError(
7853
+ "AUTH_REQUIRED",
7854
+ "The Open Link token is no longer valid. Ask the link administrator for a current token.",
7855
+ {
7856
+ exitCode: exitCodes.authRequired,
7857
+ ...details
7858
+ }
7859
+ );
7860
+ }
7815
7861
  if (normalizedProblemCode === "document_title_conflict") {
7816
7862
  return new SkillError("DOCUMENT_TITLE_CONFLICT", "The document title conflicts", {
7817
7863
  exitCode: exitCodes.configConflict,
@@ -9036,32 +9082,65 @@ function addSkillCommands(program, dependencies2) {
9036
9082
  []
9037
9083
  );
9038
9084
  command.option("--origin <origin>", "Full SAG HTTP or HTTPS Origin");
9039
- command.action(async (options) => {
9040
- if (options.origin) {
9041
- const account = dependencies2.skillAccount;
9042
- if (!account) {
9043
- throw new CliError(
9044
- "DEPENDENCY_MISSING",
9045
- "SAG account configuration is unavailable",
9046
- { exitCode: exitCodes.dependencyMissing }
9047
- );
9085
+ command.option(
9086
+ "--link-token <token>",
9087
+ "Open Link token; replaces the saved authorization for this Origin"
9088
+ );
9089
+ command.action(
9090
+ async (options) => {
9091
+ if (options.linkToken && !options.origin) {
9092
+ throw new CliError("INVALID_ARGUMENT", "--link-token requires --origin", {
9093
+ exitCode: exitCodes.invalidArgument
9094
+ });
9095
+ }
9096
+ if (options.origin) {
9097
+ const account = dependencies2.skillAccount;
9098
+ if (!account) {
9099
+ throw new CliError(
9100
+ "DEPENDENCY_MISSING",
9101
+ "SAG account configuration is unavailable",
9102
+ { exitCode: exitCodes.dependencyMissing }
9103
+ );
9104
+ }
9105
+ if (options.linkToken) {
9106
+ await account.config.saveLinkToken(options.origin, options.linkToken);
9107
+ } else {
9108
+ await account.config.setCurrentOrigin(options.origin);
9109
+ }
9048
9110
  }
9049
- await account.config.setCurrentOrigin(options.origin);
9111
+ await executeSkillTargets(
9112
+ program,
9113
+ dependencies2,
9114
+ installSkillTargets(skillInstallerRuntime(dependencies2), {
9115
+ ...options.agent.length ? { agents: options.agent } : {},
9116
+ yes: commandOptions2(program).yes ?? false,
9117
+ update: name === "update"
9118
+ })
9119
+ );
9050
9120
  }
9051
- await executeSkillTargets(
9052
- program,
9053
- dependencies2,
9054
- installSkillTargets(skillInstallerRuntime(dependencies2), {
9055
- ...options.agent.length ? { agents: options.agent } : {},
9056
- yes: commandOptions2(program).yes ?? false,
9057
- update: name === "update"
9058
- })
9059
- );
9060
- });
9121
+ );
9061
9122
  };
9062
9123
  addInstall("install", "Install SAG Knowledge for every detected Agent");
9063
9124
  addInstall("update", "Resolve the running @latest package and update managed Skills");
9064
9125
  const auth = skill.command("auth").description("Authorize one SAG account Origin");
9126
+ auth.command("paste-token").description("Save an Open Link token for one SAG Origin").requiredOption("--origin <origin>", "Full SAG HTTP or HTTPS Origin").requiredOption("--token <token>", "Open Link token provided by an administrator").action(async (options) => {
9127
+ const account = dependencies2.skillAccount;
9128
+ if (!account) {
9129
+ throw new CliError(
9130
+ "DEPENDENCY_MISSING",
9131
+ "SAG account configuration is unavailable",
9132
+ {
9133
+ exitCode: exitCodes.dependencyMissing
9134
+ }
9135
+ );
9136
+ }
9137
+ await account.config.saveLinkToken(options.origin, options.token);
9138
+ emit(program, dependencies2, {
9139
+ origin: normalizeSkillOrigin(options.origin),
9140
+ authorized: true,
9141
+ method: "open_link"
9142
+ });
9143
+ });
9065
9144
  auth.command("login").description("Open browser approval and authorize the current SAG account").option("--origin <origin>", "Full SAG HTTP or HTTPS Origin").action(async (options) => {
9066
9145
  const origin = await resolveSkillOrigin(dependencies2, options.origin, true);
9067
9146
  emit(
@@ -9072,11 +9151,21 @@ function addSkillCommands(program, dependencies2) {
9072
9151
  });
9073
9152
  auth.command("status").description("Inspect the saved SAG account authorization").option("--origin <origin>", "Full SAG HTTP or HTTPS Origin").action(async (options) => {
9074
9153
  const origin = await resolveSkillOrigin(dependencies2, options.origin);
9075
- const account = await skillAccountAuthRuntime(dependencies2).config.getAccount(origin);
9154
+ const configured = dependencies2.skillAccount;
9155
+ if (!configured) {
9156
+ throw new CliError(
9157
+ "DEPENDENCY_MISSING",
9158
+ "SAG account configuration is unavailable",
9159
+ {
9160
+ exitCode: exitCodes.dependencyMissing
9161
+ }
9162
+ );
9163
+ }
9164
+ const authorization = await configured.config.getAuthorization(origin);
9076
9165
  emit(program, dependencies2, {
9077
- authenticated: Boolean(account),
9166
+ authenticated: Boolean(authorization),
9078
9167
  origin,
9079
- ...account ? { user: account.user } : {}
9168
+ ...authorization && "kind" in authorization ? { method: "open_link" } : authorization ? { method: "browser", user: authorization.user } : {}
9080
9169
  });
9081
9170
  });
9082
9171
  auth.command("logout").description("Revoke and remove the saved SAG account authorization").option("--origin <origin>", "Full SAG HTTP or HTTPS Origin").action(async (options) => {