@actionway/cli-dev 0.0.0-dev.33149579708.3faf5a7ef0f4 → 0.0.0-dev.33150518878.23b075e58bd0

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 (3) hide show
  1. package/README.md +2 -0
  2. package/dist/index.js +65 -42
  3. package/package.json +6 -6
package/README.md CHANGED
@@ -53,6 +53,8 @@ actionway --agent-host=workbuddy tools search "generate a product image"
53
53
  短码与 `{public origin}/cli/activate` 验证 URL,用户在任意设备的浏览器上登录并
54
54
  批准后 CLI 轮询取回一次性授权码并在本地完成 PKCE token 交换(远端 / headless /
55
55
  WSL 环境可直接使用,`--no-browser` 仅打印 URL 不尝试开浏览器);
56
+ fresh `actionway init` 会在 token 交换后的第一条账户请求中携带安装会话和本地
57
+ 客户端上下文,由服务端同时完成 CLI 首次建户、获客归因和安装连接;
56
58
  凭据存 `~/.actionway/credentials.json`(POSIX 上为 0600 owner-only 文件;
57
59
  Windows 上 chmod 无效,保密性依赖 `%USERPROFILE%` 的继承 ACL——不要把
58
60
  `ACTIONWAY_CONFIG_DIR` 指到共享目录)。CLI 从不打印或存储 OAuth client secret。
package/dist/index.js CHANGED
@@ -12407,6 +12407,35 @@ function runUpdate(options = {}) {
12407
12407
  return { ...status, updated: true, restart_required: true };
12408
12408
  }
12409
12409
 
12410
+ // src/lib/client-context.ts
12411
+ var ACTIONWAY_AGENT_HOST_HEADER = "x-actionway-agent-host";
12412
+ var ACTIONWAY_RUNTIME_OS_HEADER = "x-actionway-runtime-os";
12413
+ var ACTIONWAY_AGENT_HOSTS = ["codex", "claude_code", "workbuddy"];
12414
+ function isActionwayAgentHost(value) {
12415
+ return typeof value === "string" && ACTIONWAY_AGENT_HOSTS.includes(value);
12416
+ }
12417
+ function detectRuntimeOs(platform = process.platform, env = process.env) {
12418
+ if (platform === "win32") return "windows";
12419
+ if (platform === "darwin") return "macos";
12420
+ if (platform === "linux") {
12421
+ if ((env.WSL_DISTRO_NAME ?? "").trim() || (env.WSL_INTEROP ?? "").trim()) return "wsl";
12422
+ return "linux";
12423
+ }
12424
+ return "other";
12425
+ }
12426
+ function localClientContext(agentHost, platform = process.platform, env = process.env) {
12427
+ return {
12428
+ ...isActionwayAgentHost(agentHost) ? { agentHost } : {},
12429
+ runtimeOs: detectRuntimeOs(platform, env)
12430
+ };
12431
+ }
12432
+ function localClientContextHeaders(context) {
12433
+ return {
12434
+ ...context.agentHost ? { [ACTIONWAY_AGENT_HOST_HEADER]: context.agentHost } : {},
12435
+ [ACTIONWAY_RUNTIME_OS_HEADER]: context.runtimeOs
12436
+ };
12437
+ }
12438
+
12410
12439
  // src/auth/clerk.ts
12411
12440
  var DEFAULT_GATEWAY_URL = "https://actionway.ai";
12412
12441
  var SCOPES = "profile email offline_access";
@@ -12680,9 +12709,19 @@ async function loadFreshCredentials(env = process.env, fetchImpl = fetch) {
12680
12709
  saveCredentials(next, env);
12681
12710
  return next;
12682
12711
  }
12683
- async function fetchCliSession(gateway, accessToken, fetchImpl = fetch) {
12684
- const response = await fetchImpl(`${stripSlash(gateway)}/api/auth/cli-session`, {
12685
- headers: { Accept: "application/json", Authorization: `Bearer ${accessToken}` },
12712
+ async function fetchCliSession(gateway, accessToken, fetchImpl = fetch, context = {}) {
12713
+ const url = new URL(`${stripSlash(gateway)}/api/auth/cli-session`);
12714
+ if (context.installAttribution) {
12715
+ url.searchParams.set("install_session_id", context.installAttribution.installSessionId);
12716
+ url.searchParams.set("install_source", context.installAttribution.installSource);
12717
+ }
12718
+ const response = await fetchImpl(url, {
12719
+ headers: {
12720
+ Accept: "application/json",
12721
+ Authorization: `Bearer ${accessToken}`,
12722
+ "x-actionway-cli-version": getCliVersion(),
12723
+ ...context.clientContext ? localClientContextHeaders(context.clientContext) : {}
12724
+ },
12686
12725
  signal: AbortSignal.timeout(SESSION_TIMEOUT_MS)
12687
12726
  });
12688
12727
  if (response.status === 401) return null;
@@ -12808,7 +12847,10 @@ ${pairing.verificationUrlComplete}`);
12808
12847
  }),
12809
12848
  fetchImpl
12810
12849
  );
12811
- const account = await fetchCliSession(gateway, tokens.accessToken, fetchImpl);
12850
+ const account = await fetchCliSession(gateway, tokens.accessToken, fetchImpl, {
12851
+ ...options.installAttribution ? { installAttribution: options.installAttribution } : {},
12852
+ ...options.clientContext ? { clientContext: options.clientContext } : {}
12853
+ });
12812
12854
  if (!account) {
12813
12855
  throw new CliError("E_BACKEND", "Actionway did not accept the OAuth token", "run `actionway login` again");
12814
12856
  }
@@ -12882,7 +12924,7 @@ function failFromError2(err, fallbackHint) {
12882
12924
  ...fallbackHint ? { hint: fallbackHint } : {}
12883
12925
  });
12884
12926
  }
12885
- function registerAuthCommands(program2) {
12927
+ function registerAuthCommands(program2, getClientContext = () => ({ runtimeOs: "other" })) {
12886
12928
  program2.command("login").description("Authenticate with Actionway by approving a one-time code in any browser (Clerk OAuth with PKCE).").option("--gateway <url>", "Actionway public origin").option("--client-id <id>", "Actionway OAuth client id (must be paired with --issuer; default: both discovered from the public origin)").option("--issuer <url>", "Actionway OAuth issuer (must be paired with --client-id; default: both discovered from the public origin)").option("--timeout-seconds <n>", "how long to wait for the sign-in to be approved").option("--no-browser", "print the verification URL instead of opening a browser (use on remote/headless machines)").action(async (opts) => {
12887
12929
  try {
12888
12930
  const { credentials, account } = await login({
@@ -12891,6 +12933,7 @@ function registerAuthCommands(program2) {
12891
12933
  ...opts.issuer ? { issuer: opts.issuer } : {},
12892
12934
  ...opts.timeoutSeconds ? { timeoutSeconds: Number(opts.timeoutSeconds) } : {},
12893
12935
  ...opts.browser === false ? { noBrowser: true } : {},
12936
+ clientContext: getClientContext(),
12894
12937
  // 授权 URL / 浏览器提示走 stderr NDJSON 事件(stdout 保持结果协议)。
12895
12938
  onNotice: (message) => emitEvent({ event: "auth", message })
12896
12939
  });
@@ -13266,35 +13309,6 @@ function materializeSkill(options = {}) {
13266
13309
  };
13267
13310
  }
13268
13311
 
13269
- // src/lib/client-context.ts
13270
- var ACTIONWAY_AGENT_HOST_HEADER = "x-actionway-agent-host";
13271
- var ACTIONWAY_RUNTIME_OS_HEADER = "x-actionway-runtime-os";
13272
- var ACTIONWAY_AGENT_HOSTS = ["codex", "claude_code", "workbuddy"];
13273
- function isActionwayAgentHost(value) {
13274
- return typeof value === "string" && ACTIONWAY_AGENT_HOSTS.includes(value);
13275
- }
13276
- function detectRuntimeOs(platform = process.platform, env = process.env) {
13277
- if (platform === "win32") return "windows";
13278
- if (platform === "darwin") return "macos";
13279
- if (platform === "linux") {
13280
- if ((env.WSL_DISTRO_NAME ?? "").trim() || (env.WSL_INTEROP ?? "").trim()) return "wsl";
13281
- return "linux";
13282
- }
13283
- return "other";
13284
- }
13285
- function localClientContext(agentHost, platform = process.platform, env = process.env) {
13286
- return {
13287
- ...isActionwayAgentHost(agentHost) ? { agentHost } : {},
13288
- runtimeOs: detectRuntimeOs(platform, env)
13289
- };
13290
- }
13291
- function localClientContextHeaders(context) {
13292
- return {
13293
- ...context.agentHost ? { [ACTIONWAY_AGENT_HOST_HEADER]: context.agentHost } : {},
13294
- [ACTIONWAY_RUNTIME_OS_HEADER]: context.runtimeOs
13295
- };
13296
- }
13297
-
13298
13312
  // src/lib/install-session.ts
13299
13313
  var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
13300
13314
  var ANALYTICS_TIMEOUT_MS = 3e3;
@@ -13445,23 +13459,32 @@ function registerInitCommand(program2, getClientContext = () => ({ runtimeOs: "o
13445
13459
  clientContext
13446
13460
  });
13447
13461
  let loginStarted = false;
13462
+ let account;
13448
13463
  if (!whoamiSnapshot()) {
13449
13464
  loginStarted = true;
13450
- await login({
13465
+ const loginResult = await login({
13451
13466
  ...opts.gateway ? { gateway: opts.gateway } : {},
13452
13467
  ...opts.clientId ? { clientId: opts.clientId } : {},
13453
13468
  ...opts.issuer ? { issuer: opts.issuer } : {},
13454
13469
  ...opts.timeoutSeconds ? { timeoutSeconds: Number(opts.timeoutSeconds) } : {},
13455
13470
  ...opts.browser === false ? { noBrowser: true } : {},
13471
+ installAttribution: { installSessionId, installSource },
13472
+ clientContext,
13456
13473
  onNotice: (message) => emitEvent({ event: "auth", message })
13457
13474
  });
13475
+ account = {
13476
+ userId: loginResult.account.userId,
13477
+ workspaceId: loginResult.account.workspaceId,
13478
+ walletId: loginResult.account.walletId
13479
+ };
13480
+ } else {
13481
+ account = await connectInstallSession({
13482
+ ...opts.gateway ? { explicitGateway: opts.gateway } : {},
13483
+ installSessionId,
13484
+ installSource,
13485
+ clientContext
13486
+ });
13458
13487
  }
13459
- const account = await connectInstallSession({
13460
- ...opts.gateway ? { explicitGateway: opts.gateway } : {},
13461
- installSessionId,
13462
- installSource,
13463
- clientContext
13464
- });
13465
13488
  const snapshot = whoamiSnapshot();
13466
13489
  ok({
13467
13490
  initialized: true,
@@ -13797,7 +13820,7 @@ function buildProgram() {
13797
13820
  registerDoctorCommand(program2);
13798
13821
  registerUpdateCommand(program2);
13799
13822
  registerDevelopmentStatusCommand(program2);
13800
- registerAuthCommands(program2);
13823
+ registerAuthCommands(program2, getClientContext);
13801
13824
  registerAccountCommands(program2, getTransport2);
13802
13825
  registerToolsCommands(program2, getTransport2);
13803
13826
  registerActionCommand(program2, generate_video_default, actionDeps);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actionway/cli-dev",
3
- "version": "0.0.0-dev.33149579708.3faf5a7ef0f4",
3
+ "version": "0.0.0-dev.33150518878.23b075e58bd0",
4
4
  "description": "Actionway development CLI for dev.actionway.ai",
5
5
  "type": "module",
6
6
  "bin": {
@@ -19,8 +19,8 @@
19
19
  "tsx": "^4.20.0",
20
20
  "typescript": "7.0.2",
21
21
  "vitest": "^3.2.7",
22
- "@actionway/cli-core": "0.1.0",
23
- "@actionway/contracts": "0.1.0"
22
+ "@actionway/contracts": "0.1.0",
23
+ "@actionway/cli-core": "0.1.0"
24
24
  },
25
25
  "engines": {
26
26
  "node": ">=20"
@@ -36,9 +36,9 @@
36
36
  },
37
37
  "actionway": {
38
38
  "channel": "development",
39
- "source_sha": "3faf5a7ef0f4a67fc6a17ee4f57741b938e0a0e2",
40
- "run_id": 33149579708,
41
- "run_url": "https://github.com/PawLogic/actionway/actions/runs/33149579708",
39
+ "source_sha": "23b075e58bd0e275ab8d8667869b75bfdd8a656d",
40
+ "run_id": 33150518878,
41
+ "run_url": "https://github.com/PawLogic/actionway/actions/runs/33150518878",
42
42
  "gateway_url": "https://dev.actionway.ai"
43
43
  }
44
44
  }