linkque-cli-v2 1.0.6 → 1.1.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/linkquejs.js CHANGED
@@ -20363,31 +20363,27 @@ function parseEnvEntry(raw) {
20363
20363
  var import_fs6 = require("fs");
20364
20364
  var import_path9 = require("path");
20365
20365
  var INTEGRATE_PKG = "@alipay/linkque-agent-appwrite-integrate";
20366
- var resolveIntegrateRoot = () => resolveInstalledIntegrateRoot() ?? resolvePortableIntegrateRoot();
20366
+ var resolveIntegrateRoot = () => resolvePortableIntegrateRoot() ?? resolveInstalledIntegrateRoot();
20367
20367
  var resolveInstalledIntegrateRoot = () => {
20368
20368
  try {
20369
20369
  return (0, import_path9.dirname)(require.resolve(`${INTEGRATE_PKG}/package.json`));
20370
20370
  } catch {
20371
- return void 0;
20371
+ throw new LinkqueCliError(
20372
+ "AGENTBUILD_INTEGRATE_NOT_BUILT",
20373
+ "@alipay/linkque-agent-appwrite-integrate \u672A\u5B89\u88C5\uFF0C\u4E14 public bundle \u672A\u643A\u5E26 vendor \u6784\u5EFA\u8D44\u4EA7"
20374
+ );
20372
20375
  }
20373
20376
  };
20374
20377
  var resolvePortableIntegrateRoot = () => {
20375
20378
  let dir = __dirname;
20376
20379
  while (true) {
20377
- const candidate = (0, import_path9.join)(
20378
- dir,
20379
- "vendor",
20380
- "linkque-agent-appwrite-integrate"
20381
- );
20380
+ const candidate = (0, import_path9.join)(dir, "vendor", "linkque-agent-appwrite-integrate");
20382
20381
  if ((0, import_fs6.existsSync)((0, import_path9.join)(candidate, "package.json"))) return candidate;
20383
20382
  const parent = (0, import_path9.dirname)(dir);
20384
20383
  if (parent === dir) break;
20385
20384
  dir = parent;
20386
20385
  }
20387
- throw new LinkqueCliError(
20388
- "AGENTBUILD_INTEGRATE_NOT_BUILT",
20389
- "@alipay/linkque-agent-appwrite-integrate \u672A\u5B89\u88C5\uFF0C\u4E14 public bundle \u672A\u643A\u5E26 vendor \u6784\u5EFA\u8D44\u4EA7"
20390
- );
20386
+ return void 0;
20391
20387
  };
20392
20388
  var assertIntegrateBuilt = (pkgRoot) => {
20393
20389
  const distEsm = (0, import_path9.join)(pkgRoot, "dist", "esm");
@@ -25453,6 +25449,20 @@ function getJsonSchemaIssues(value, path22 = "schema", options = {}) {
25453
25449
  validateSchemaNode(value, path22, issues, options);
25454
25450
  return issues;
25455
25451
  }
25452
+ var OPAQUE_OBJECT_SCHEMA = {
25453
+ type: "object",
25454
+ additionalProperties: true
25455
+ };
25456
+ function normalizeMcpOutputSchema(value) {
25457
+ if (!isPlainRecord(value) || getJsonSchemaIssues(value).length > 0) {
25458
+ return { schema: { ...OPAQUE_OBJECT_SCHEMA }, mode: "opaque" };
25459
+ }
25460
+ const schema = cloneJsonValue(value);
25461
+ if (schema.type === "object" && (!isPlainRecord(schema.properties) || Object.keys(schema.properties).length === 0) && !isPlainRecord(schema.additionalProperties)) {
25462
+ return { schema: { ...OPAQUE_OBJECT_SCHEMA }, mode: "opaque" };
25463
+ }
25464
+ return { schema, mode: "declared" };
25465
+ }
25456
25466
  function normalizeTargetJsonSchema(schema) {
25457
25467
  const cloned = JSON.parse(JSON.stringify(schema));
25458
25468
  normalizeObjectDefaults(cloned);
@@ -25905,7 +25915,7 @@ function parseA2UICardBindingContext(value) {
25905
25915
  const issues = getA2UICardBindingContextIssues(value);
25906
25916
  return issues.length > 0 ? { success: false, issues } : {
25907
25917
  success: true,
25908
- data: JSON.parse(JSON.stringify(value)),
25918
+ data: normalizeBindingContext(value),
25909
25919
  issues: []
25910
25920
  };
25911
25921
  }
@@ -26052,11 +26062,7 @@ function validateA2UICardBindings(input, options = {}) {
26052
26062
  issues.push(issue2(`fields.${field.fieldId}`, "MCP_TOOL_UNAVAILABLE", `MCP tool ${binding.toolName} is absent from binding context`));
26053
26063
  continue;
26054
26064
  }
26055
- const transform = validateA2UICardTransform(binding.transform, {
26056
- fieldId: field.fieldId,
26057
- sourceSchema: tool.outputSchema,
26058
- targetSchema: field.valueSchema
26059
- });
26065
+ const transform = validateA2UICardTransform(binding.transform);
26060
26066
  issues.push(...transform.issues.map((entry) => ({
26061
26067
  ...entry,
26062
26068
  path: `fields.${field.fieldId}.${entry.path}`
@@ -26127,6 +26133,7 @@ function validateTool(value, path22, resourceId, issues) {
26127
26133
  "description",
26128
26134
  "inputSchema",
26129
26135
  "outputSchema",
26136
+ "outputSchemaMode",
26130
26137
  "annotations"
26131
26138
  ], path22, issues);
26132
26139
  if (value.resourceId !== resourceId) {
@@ -26136,11 +26143,28 @@ function validateTool(value, path22, resourceId, issues) {
26136
26143
  issues.push(issue2(`${path22}.toolName`, "CARD_BINDING_CONTEXT_INVALID", "toolName is required"));
26137
26144
  }
26138
26145
  issues.push(...getJsonSchemaIssues(value.inputSchema, `${path22}.inputSchema`));
26139
- issues.push(...getJsonSchemaIssues(value.outputSchema, `${path22}.outputSchema`));
26140
- if (isPlainRecord(value.annotations) && value.annotations.readOnlyHint === false) {
26141
- issues.push(issue2(`${path22}.annotations`, "CARD_BINDING_CONTEXT_INVALID", "tool explicitly declares readOnlyHint=false"));
26146
+ if (value.outputSchemaMode !== void 0 && value.outputSchemaMode !== "declared" && value.outputSchemaMode !== "opaque") {
26147
+ issues.push(issue2(`${path22}.outputSchemaMode`, "CARD_BINDING_CONTEXT_INVALID", "outputSchemaMode must be declared or opaque"));
26142
26148
  }
26143
26149
  }
26150
+ function normalizeBindingContext(context) {
26151
+ const cloned = JSON.parse(JSON.stringify(context));
26152
+ cloned.candidates = cloned.candidates.map((candidate) => {
26153
+ if (candidate.status !== "ready")
26154
+ return candidate;
26155
+ const normalized = normalizeMcpOutputSchema(candidate.tool.outputSchema);
26156
+ const mode2 = normalized.mode === "opaque" || candidate.tool.outputSchemaMode === "opaque" ? "opaque" : "declared";
26157
+ return {
26158
+ ...candidate,
26159
+ tool: {
26160
+ ...candidate.tool,
26161
+ outputSchema: normalized.schema,
26162
+ outputSchemaMode: mode2
26163
+ }
26164
+ };
26165
+ });
26166
+ return cloned;
26167
+ }
26144
26168
  function validatePreferences(value, path22, issues) {
26145
26169
  if (value === void 0)
26146
26170
  return;
@@ -27154,7 +27178,7 @@ function compileV3Resource(draft, revision, bindings, tools) {
27154
27178
  purpose: binding.purpose,
27155
27179
  required: binding.required,
27156
27180
  ...binding.dependsOn?.length ? { dependsOn: [...binding.dependsOn] } : {},
27157
- outputSchema: tool?.outputSchema ?? {}
27181
+ outputSchema: normalizeMcpOutputSchema(tool?.outputSchema).schema
27158
27182
  };
27159
27183
  const previous = sourceById.get(source.sourceId);
27160
27184
  if (previous && stableJsonStringify(previous) !== stableJsonStringify(source)) {
@@ -27604,7 +27628,10 @@ async function validateCardBindingsFromDisk(cwd, draftId, expectedContextChecksu
27604
27628
  }
27605
27629
  const context = contextResult.data;
27606
27630
  const actualContextChecksum = createA2UICardBindingContextChecksum(context);
27607
- if (actualContextChecksum !== expectedContextChecksum) {
27631
+ const legacyContextChecksum = createA2UICardBindingContextChecksum(
27632
+ contextValue
27633
+ );
27634
+ if (actualContextChecksum !== expectedContextChecksum && legacyContextChecksum !== expectedContextChecksum) {
27608
27635
  throw new LinkqueCliError(
27609
27636
  "CARD_BINDING_CONTEXT_STALE",
27610
27637
  "\u7ED1\u5B9A\u4E0A\u4E0B\u6587\u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77 AI \u8F85\u52A9\u7ED1\u5B9A"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "linkque-cli-v2",
3
- "version": "1.0.6",
3
+ "version": "1.1.0",
4
4
  "description": "Public Linkque CLI bundle for sandbox debugging",
5
5
  "bin": {
6
6
  "linkquejs": "linkquejs.js"
@@ -7328,6 +7328,109 @@ var require_agent = __commonJS({
7328
7328
  }
7329
7329
  });
7330
7330
 
7331
+ // ../linkque-agent-appwrite-integrate/dist/esm/runtime/auth.js
7332
+ var LINKQUE_AUTHORIZATION_HEADER = "x-linkque-authorization";
7333
+ var LinkqueGatewayAuthError = class extends Error {
7334
+ code = "invalid_linkque_authorization";
7335
+ status = 401;
7336
+ constructor(message = "X-Linkque-Authorization \u5FC5\u987B\u662F\u5355\u4E2A Bearer \u51ED\u636E") {
7337
+ super(message);
7338
+ this.name = "LinkqueGatewayAuthError";
7339
+ }
7340
+ };
7341
+ var LinkqueGatewayAuthUnconfiguredError = class extends Error {
7342
+ code = "auth_unconfigured";
7343
+ status = 500;
7344
+ constructor(message = "\u8BA4\u8BC1\u914D\u7F6E\u7F3A\u5931:LINKQUE_AGENT_ACCESS_KEY \u672A\u8BBE\u7F6E") {
7345
+ super(message);
7346
+ this.name = "LinkqueGatewayAuthUnconfiguredError";
7347
+ }
7348
+ };
7349
+ function resolveLinkqueGatewayAuth(headers, env = process.env, logCtx) {
7350
+ const log = (...a2) => logCtx?.log?.("[auth-resolve]", ...a2);
7351
+ const logError = (...a2) => logCtx?.error?.("[auth-resolve]", ...a2);
7352
+ log("stage=start");
7353
+ const matches = Object.entries(headers ?? {}).filter(([key]) => key.toLowerCase() === LINKQUE_AUTHORIZATION_HEADER);
7354
+ if (matches.length > 0) {
7355
+ log(`stage=header-inspection, state=present, count=${matches.length}`);
7356
+ log("stage=user-token-validation, state=start");
7357
+ if (matches.length !== 1) {
7358
+ logError("stage=failed, reason=duplicate-header");
7359
+ throw new LinkqueGatewayAuthError();
7360
+ }
7361
+ const value = matches[0]?.[1];
7362
+ if (typeof value !== "string") {
7363
+ logError("stage=failed, reason=multi-value-header");
7364
+ throw new LinkqueGatewayAuthError();
7365
+ }
7366
+ if (value.includes(",")) {
7367
+ logError("stage=failed, reason=joined-header");
7368
+ throw new LinkqueGatewayAuthError();
7369
+ }
7370
+ const match = /^Bearer[\t ]+([^\s,]+)$/iu.exec(value.trim());
7371
+ const token = match?.[1];
7372
+ if (!token) {
7373
+ logError("stage=failed, reason=invalid-bearer-format");
7374
+ throw new LinkqueGatewayAuthError();
7375
+ }
7376
+ log("stage=user-token-validation, state=success, scheme=Bearer");
7377
+ const provider2 = resolveProvider(env.LINKQUE_MODEL_PROVIDER, log, logError);
7378
+ log("stage=complete, mode=user-token, source=request-header");
7379
+ return {
7380
+ mode: "user-token",
7381
+ modelCredential: token,
7382
+ authorizationHeader: `Bearer ${token}`,
7383
+ auth: { provider: provider2, apiKey: token }
7384
+ };
7385
+ }
7386
+ log("stage=header-inspection, state=absent");
7387
+ log("stage=aak-fallback, state=start, source=env:LINKQUE_AGENT_ACCESS_KEY");
7388
+ const apiKey = env.LINKQUE_AGENT_ACCESS_KEY?.trim();
7389
+ if (!apiKey) {
7390
+ logError("stage=failed, reason=aak-unconfigured");
7391
+ throw new LinkqueGatewayAuthUnconfiguredError();
7392
+ }
7393
+ log("stage=aak-fallback, state=configured");
7394
+ const provider = resolveProvider(env.LINKQUE_MODEL_PROVIDER, log, logError);
7395
+ log("stage=complete, mode=aak, source=env:LINKQUE_AGENT_ACCESS_KEY");
7396
+ return {
7397
+ mode: "aak",
7398
+ modelCredential: apiKey,
7399
+ authorizationHeader: `aak ${apiKey}`,
7400
+ auth: { provider, apiKey }
7401
+ };
7402
+ }
7403
+ function resolveGatewayAuthContext(gatewayAuth, env = process.env, logCtx, caller = "unknown") {
7404
+ const log = (...a2) => logCtx?.log?.("[auth-resolve]", ...a2);
7405
+ if (gatewayAuth) {
7406
+ log(`stage=context-selection, caller=${caller}, branch=request-context, mode=${gatewayAuth.mode}`);
7407
+ return gatewayAuth;
7408
+ }
7409
+ log(`stage=context-selection, caller=${caller}, branch=compat-env-fallback`);
7410
+ return resolveLinkqueGatewayAuth(void 0, env, logCtx);
7411
+ }
7412
+ function parseProvider(raw) {
7413
+ if (!raw)
7414
+ return "LINKQUE";
7415
+ const upper = raw.toUpperCase();
7416
+ if (upper === "LINKQUE")
7417
+ return "LINKQUE";
7418
+ if (upper === "TEST")
7419
+ return "TEST";
7420
+ throw new Error(`\u4E0D\u652F\u6301\u7684 LINKQUE_MODEL_PROVIDER="${raw}"(\u5F53\u524D\u652F\u6301:LINKQUE\u3001TEST)`);
7421
+ }
7422
+ function resolveProvider(raw, log, logError) {
7423
+ log("stage=provider-resolution, state=start");
7424
+ try {
7425
+ const provider = parseProvider(raw);
7426
+ log(`stage=provider-resolution, state=success, provider=${provider}`);
7427
+ return provider;
7428
+ } catch (error) {
7429
+ logError("stage=failed, reason=invalid-provider");
7430
+ throw error;
7431
+ }
7432
+ }
7433
+
7331
7434
  // ../../node_modules/node-fetch-native-with-agent/dist/index.mjs
7332
7435
  var a = Object.defineProperty;
7333
7436
  var t = (e, r) => a(e, "name", { value: r, configurable: true });
@@ -11699,7 +11802,7 @@ function apiKeySource(env, hasRequestKey) {
11699
11802
  }
11700
11803
  function describeRuntimeEnv(env, hasRequestKey = false) {
11701
11804
  const lines = [];
11702
- lines.push(envLine("LINKQUE_AGENT_ACCESS_KEY", maskSecret(env.LINKQUE_AGENT_ACCESS_KEY?.trim())));
11805
+ lines.push(envLine("LINKQUE_AGENT_ACCESS_KEY", env.LINKQUE_AGENT_ACCESS_KEY?.trim() ? "<set>" : "<unset>"));
11703
11806
  lines.push(envLine("LINKQUE_MODEL_PROVIDER", envValue(env, "LINKQUE_MODEL_PROVIDER")));
11704
11807
  lines.push(envLine("APPBASE_ENDPOINT", `${maskEndpoint(firstHit(env, ENDPOINT_SOURCES))}(src=${whichSource(env, ENDPOINT_SOURCES)})`));
11705
11808
  lines.push(envLine("APPBASE_PROJECT_ID", `${firstHit(env, PROJECT_SOURCES)}(src=${whichSource(env, PROJECT_SOURCES)})`));
@@ -11954,7 +12057,7 @@ async function clientCapability(ctx) {
11954
12057
  result = await runClientCapability(readAppwriteTrigger(ctx.req.headers), ctx.req.method, resolveBodyJSON(ctx.req), readAuthenticatedUserId(ctx.req.headers), store);
11955
12058
  } catch (error) {
11956
12059
  ctx.error?.(error);
11957
- result = jsonError(500, "internal_error", error instanceof Error ? error.message : "unknown error");
12060
+ result = error instanceof LinkqueGatewayAuthError || error instanceof LinkqueGatewayAuthUnconfiguredError ? jsonError(error.status, error.code, error.message) : jsonError(500, "internal_error", error instanceof Error ? error.message : "unknown error");
11958
12061
  }
11959
12062
  return ctx.res.json?.(result.body, result.status);
11960
12063
  }
@@ -11993,6 +12096,10 @@ function requiredEnv(name) {
11993
12096
  }
11994
12097
 
11995
12098
  export {
12099
+ LinkqueGatewayAuthError,
12100
+ LinkqueGatewayAuthUnconfiguredError,
12101
+ resolveLinkqueGatewayAuth,
12102
+ resolveGatewayAuthContext,
11996
12103
  resolveBodyJSON,
11997
12104
  toAgentRunMessages,
11998
12105
  jsonError,
@@ -12001,7 +12108,6 @@ export {
12001
12108
  readAuthenticatedUserId,
12002
12109
  readAppwriteApiKey,
12003
12110
  Query,
12004
- maskSecret,
12005
12111
  isDebugLogLevel,
12006
12112
  describeRuntimeEnv,
12007
12113
  resolveRunStorage,