@scheduler-systems/gal-run 0.0.388 → 0.0.390

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 (2) hide show
  1. package/dist/index.cjs +113 -12
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -3970,7 +3970,7 @@ var cliVersion, defaultApiUrl, BUILD_CONSTANTS, constants_default;
3970
3970
  var init_constants = __esm({
3971
3971
  "src/constants.ts"() {
3972
3972
  "use strict";
3973
- cliVersion = true ? "0.0.388" : "0.0.0-dev";
3973
+ cliVersion = true ? "0.0.390" : "0.0.0-dev";
3974
3974
  defaultApiUrl = true ? "https://api.gal.run" : "http://localhost:3000";
3975
3975
  BUILD_CONSTANTS = Object.freeze([cliVersion, defaultApiUrl]);
3976
3976
  constants_default = BUILD_CONSTANTS;
@@ -4880,7 +4880,7 @@ function detectEnvironment() {
4880
4880
  return "dev";
4881
4881
  }
4882
4882
  try {
4883
- const version2 = true ? "0.0.388" : void 0;
4883
+ const version2 = true ? "0.0.390" : void 0;
4884
4884
  if (version2 && version2.includes("-local")) {
4885
4885
  return "dev";
4886
4886
  }
@@ -5249,7 +5249,7 @@ function getId() {
5249
5249
  }
5250
5250
  function getCliVersion() {
5251
5251
  try {
5252
- return true ? "0.0.388" : "0.0.0-dev";
5252
+ return true ? "0.0.390" : "0.0.0-dev";
5253
5253
  } catch {
5254
5254
  return "0.0.0-dev";
5255
5255
  }
@@ -14502,6 +14502,53 @@ var init_capability_analyzer = __esm({
14502
14502
  }
14503
14503
  });
14504
14504
 
14505
+ // src/utils/claude-token-expiry.ts
14506
+ function formatHoursRemaining(expiresInMs) {
14507
+ return Math.max(0, Math.ceil(expiresInMs / 36e5));
14508
+ }
14509
+ async function fetchClaudeTokenExpiryStatus(params) {
14510
+ const {
14511
+ apiUrl,
14512
+ authToken,
14513
+ thresholdMs = CLAUDE_TOKEN_WARNING_THRESHOLD_MS,
14514
+ nowMs = Date.now(),
14515
+ fetchImpl = fetch
14516
+ } = params;
14517
+ try {
14518
+ const response = await fetchImpl(`${apiUrl}/api/credentials/claude/validate`, {
14519
+ method: "POST",
14520
+ headers: {
14521
+ "Content-Type": "application/json",
14522
+ Authorization: `Bearer ${authToken}`
14523
+ },
14524
+ signal: AbortSignal.timeout(3e3)
14525
+ });
14526
+ if (!response.ok) return null;
14527
+ const result = await response.json();
14528
+ if (!result.valid || !result.expiresAt) return null;
14529
+ const expiresAtMs = new Date(result.expiresAt).getTime();
14530
+ if (!Number.isFinite(expiresAtMs)) return null;
14531
+ const expiresInMs = expiresAtMs - nowMs;
14532
+ const shouldWarn = expiresInMs < thresholdMs;
14533
+ const warningMessage = shouldWarn ? `Claude token expires in ${formatHoursRemaining(expiresInMs)}h. Run: gal auth claude` : null;
14534
+ return {
14535
+ expiresAt: new Date(expiresAtMs).toISOString(),
14536
+ expiresInMs,
14537
+ shouldWarn,
14538
+ warningMessage
14539
+ };
14540
+ } catch {
14541
+ return null;
14542
+ }
14543
+ }
14544
+ var CLAUDE_TOKEN_WARNING_THRESHOLD_MS;
14545
+ var init_claude_token_expiry = __esm({
14546
+ "src/utils/claude-token-expiry.ts"() {
14547
+ "use strict";
14548
+ CLAUDE_TOKEN_WARNING_THRESHOLD_MS = 2 * 60 * 60 * 1e3;
14549
+ }
14550
+ });
14551
+
14505
14552
  // src/commands/agent-session.ts
14506
14553
  function printAnalysis(analysis) {
14507
14554
  console.log(source_default.blue.bold("\n\u2500\u2500 Dry-run: Capability Analysis \u2500\u2500\n"));
@@ -14533,6 +14580,16 @@ function printAnalysis(analysis) {
14533
14580
  console.log(source_default.dim("Session was NOT created (dry-run mode). Remove --dry-run to dispatch."));
14534
14581
  }
14535
14582
  }
14583
+ async function printClaudeTokenExpiryWarning(apiUrl, authToken, jsonOutput) {
14584
+ const expiryStatus = await fetchClaudeTokenExpiryStatus({ apiUrl, authToken });
14585
+ if (!expiryStatus?.warningMessage) return;
14586
+ if (jsonOutput) {
14587
+ console.error(expiryStatus.warningMessage);
14588
+ return;
14589
+ }
14590
+ console.log(source_default.yellow(`
14591
+ ! ${expiryStatus.warningMessage}`));
14592
+ }
14536
14593
  function createAgentSessionCommand() {
14537
14594
  const cmd = new Command("session").description("Manage agent execution sessions");
14538
14595
  const getRepo = () => {
@@ -14545,6 +14602,7 @@ function createAgentSessionCommand() {
14545
14602
  }
14546
14603
  return {
14547
14604
  apiUrl: config2.apiUrl || "",
14605
+ authToken,
14548
14606
  repo: new HttpSessionRepository({ apiUrl: config2.apiUrl || "", authToken })
14549
14607
  };
14550
14608
  };
@@ -14579,7 +14637,7 @@ function createAgentSessionCommand() {
14579
14637
  };
14580
14638
  cmd.command("create").description("Create a new background agent session (triggers GitHub Actions)").argument("<name>", "Session name").option("-p, --project-context <ctx>", "Project context (owner/repo, https URL, or SSH URL)").option("-b, --branch <branch>", "Git branch to checkout (optional)").option("-a, --agent <agent>", "Agent to use (claude, codex, gemini)", "claude").option(
14581
14639
  "-r, --runner-label <label>",
14582
- "Kata-backed ARC runner label (agents-standard-runc-x64, agents-medium-runc-x64, agents-high-runc-x64)",
14640
+ "Kata-backed ARC runner label (agents-standard-runc-x64, agents-medium-runc-x64, agents-high-runc-x64, agents-kali-runc)",
14583
14641
  DEFAULT_RUNNER_LABEL
14584
14642
  ).option("--prompt <text>", "Initial prompt to run when the session starts").option("--prompt-file <path>", "Read initial prompt from a file").option("-m, --model <model>", 'Model override (e.g. "claude-sonnet-4-20250514", "gemini-3.1-pro-preview")').option("--dispatch <backend>", "Dispatch backend (auto, gha, hive)").option("--wait", "Wait until the session leaves PENDING/INITIALIZING", false).option("--timeout <ms>", "Wait timeout in milliseconds", "600000").option("--dry-run", "Analyze capabilities without creating a real session", false).option("--json", "Output as JSON", false).action(async (name, options) => {
14585
14643
  if (options.dryRun) {
@@ -14596,7 +14654,7 @@ function createAgentSessionCommand() {
14596
14654
  printAnalysis(analysis);
14597
14655
  process.exit(analysis.hasErrors ? 1 : 0);
14598
14656
  }
14599
- const { repo } = getRepo();
14657
+ const { repo, apiUrl, authToken } = getRepo();
14600
14658
  const dispatchBackend = (() => {
14601
14659
  const raw = options.dispatch?.trim();
14602
14660
  if (!raw) return void 0;
@@ -14627,6 +14685,9 @@ function createAgentSessionCommand() {
14627
14685
  dispatchBackend,
14628
14686
  model: options.model?.trim() || void 0
14629
14687
  };
14688
+ if (request.agent === "claude") {
14689
+ await printClaudeTokenExpiryWarning(apiUrl, authToken, options.json === true);
14690
+ }
14630
14691
  const spinner = ora("Creating session...").start();
14631
14692
  try {
14632
14693
  const session = await repo.create(request);
@@ -14756,7 +14817,7 @@ Next cursor: ${result.nextCursor}`));
14756
14817
  }
14757
14818
  });
14758
14819
  cmd.command("resume").description("Resume a TERMINATED session with a new prompt").argument("<session-id>", "Session ID (full UUID or prefix)").option("--prompt <text>", "Prompt to continue with").option("--prompt-file <path>", "Read resume prompt from a file").option("--dispatch <backend>", "Dispatch backend (auto, gha, hive)").option("--json", "Output as JSON", false).action(async (sessionId, options) => {
14759
- const { repo } = getRepo();
14820
+ const { repo, apiUrl, authToken } = getRepo();
14760
14821
  const spinner = ora("Resuming session...").start();
14761
14822
  try {
14762
14823
  const dispatchBackend = (() => {
@@ -14784,6 +14845,10 @@ Next cursor: ${result.nextCursor}`));
14784
14845
  }
14785
14846
  const recent = await repo.list({ limit: 100 });
14786
14847
  const resolved = await resolveSessionId(sessionId, recent.sessions || []);
14848
+ const targetSession = (recent.sessions || []).find((session) => session.id === resolved);
14849
+ if (targetSession?.agent === "claude") {
14850
+ await printClaudeTokenExpiryWarning(apiUrl, authToken, options.json === true);
14851
+ }
14787
14852
  const resp = await repo.resume(resolved, prompt2.trim(), dispatchBackend);
14788
14853
  spinner.stop();
14789
14854
  if (options.json) {
@@ -15028,6 +15093,7 @@ var init_agent_session = __esm({
15028
15093
  init_client();
15029
15094
  init_dist2();
15030
15095
  init_capability_analyzer();
15096
+ init_claude_token_expiry();
15031
15097
  SEVERITY_COLOR = {
15032
15098
  error: source_default.red,
15033
15099
  warning: source_default.yellow,
@@ -65836,23 +65902,42 @@ async function runHealthCheck() {
65836
65902
  const terms = { accepted: termsAccepted, acceptedAt: termsAcceptedAt };
65837
65903
  const config2 = ConfigManager.load();
65838
65904
  const authToken = config2.authToken || config2.apiKey;
65839
- let auth = { authenticated: false, user: null, expiresAt: null };
65905
+ let auth = {
65906
+ authenticated: false,
65907
+ user: null,
65908
+ expiresAt: null,
65909
+ claudeTokenExpiresAt: null,
65910
+ claudeTokenWarning: null
65911
+ };
65840
65912
  if (authToken) {
65841
65913
  try {
65914
+ const apiUrl = config2.apiUrl || defaultApiUrl15;
65842
65915
  const provider = new CoreServiceProvider({
65843
- apiUrl: config2.apiUrl || defaultApiUrl15,
65916
+ apiUrl,
65844
65917
  authToken
65845
65918
  });
65846
65919
  const authRepo = provider.getAuthRepository();
65847
65920
  const user = await authRepo.getCurrentUser();
65921
+ const claudeTokenExpiry = await fetchClaudeTokenExpiryStatus({
65922
+ apiUrl,
65923
+ authToken
65924
+ });
65848
65925
  auth = {
65849
65926
  authenticated: true,
65850
65927
  user: user.email || user.login || null,
65851
- expiresAt: null
65928
+ expiresAt: null,
65852
65929
  // GAL JWTs don't expose expiry in the user object
65930
+ claudeTokenExpiresAt: claudeTokenExpiry?.expiresAt ?? null,
65931
+ claudeTokenWarning: claudeTokenExpiry?.warningMessage ?? null
65853
65932
  };
65854
65933
  } catch {
65855
- auth = { authenticated: false, user: null, expiresAt: null };
65934
+ auth = {
65935
+ authenticated: false,
65936
+ user: null,
65937
+ expiresAt: null,
65938
+ claudeTokenExpiresAt: null,
65939
+ claudeTokenWarning: null
65940
+ };
65856
65941
  }
65857
65942
  }
65858
65943
  const allHealthy = cli.installed && terms.accepted && auth.authenticated;
@@ -65922,6 +66007,18 @@ function displayHealthCheck(health) {
65922
66007
  if (health.auth.authenticated) {
65923
66008
  const userDisplay = health.auth.user ? source_default.dim(health.auth.user) : source_default.dim("(signed in)");
65924
66009
  console.log(` ${CHECK} ${authLabel}${userDisplay}`);
66010
+ if (health.auth.claudeTokenExpiresAt) {
66011
+ const tokenLabel = "Claude token".padEnd(COL1);
66012
+ console.log(
66013
+ ` ${CHECK} ${tokenLabel}${source_default.dim(new Date(health.auth.claudeTokenExpiresAt).toLocaleString())}`
66014
+ );
66015
+ }
66016
+ if (health.auth.claudeTokenWarning) {
66017
+ const warningLabel = "Credential warning".padEnd(COL1);
66018
+ console.log(
66019
+ ` ${source_default.yellow("!")} ${warningLabel}${source_default.yellow(health.auth.claudeTokenWarning)}`
66020
+ );
66021
+ }
65925
66022
  } else {
65926
66023
  console.log(
65927
66024
  ` ${CROSS} ${"Auth".padEnd(COL1)}${source_default.dim("Not signed in")} \u2014 run ${source_default.cyan("`gal auth login`")}`
@@ -66064,7 +66161,10 @@ function createStatusCommand3() {
66064
66161
  }
66065
66162
  if (!health.allHealthy) {
66066
66163
  if (options.json) {
66067
- displayStatusJson({ synced: false, driftDetected: false, driftFiles: [] }, health);
66164
+ displayStatusJson(
66165
+ { synced: false, driftDetected: false, driftFiles: [], updateAvailable: false },
66166
+ health
66167
+ );
66068
66168
  } else {
66069
66169
  console.log(source_default.yellow(`Run ${source_default.cyan("`gal auth login`")} to complete setup.`));
66070
66170
  console.log();
@@ -66132,6 +66232,7 @@ var init_status = __esm({
66132
66232
  init_config_manager();
66133
66233
  init_CoreServiceProvider();
66134
66234
  init_project_detection();
66235
+ init_claude_token_expiry();
66135
66236
  init_constants();
66136
66237
  init_dist2();
66137
66238
  cliVersion6 = constants_default[0];
@@ -71039,7 +71140,7 @@ var init_index = __esm({
71039
71140
  });
71040
71141
 
71041
71142
  // src/bootstrap.ts
71042
- var cliVersion10 = true ? "0.0.388" : "0.0.0-dev";
71143
+ var cliVersion10 = true ? "0.0.390" : "0.0.0-dev";
71043
71144
  var args = process.argv.slice(2);
71044
71145
  var requestedGlobalHelp = args.length === 1 && (args[0] === "--help" || args[0] === "-h");
71045
71146
  var requestedVersion = args.length === 1 && (args[0] === "--version" || args[0] === "-V");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scheduler-systems/gal-run",
3
- "version": "0.0.388",
3
+ "version": "0.0.390",
4
4
  "description": "GAL CLI - Command-line tool for managing AI agent configurations across your organization",
5
5
  "license": "Elastic-2.0",
6
6
  "private": false,