@integrity-labs/agt-cli 0.28.506 → 0.28.508

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/bin/agt.js CHANGED
@@ -40,7 +40,7 @@ import {
40
40
  success,
41
41
  table,
42
42
  warn
43
- } from "../chunk-43UIRCO7.js";
43
+ } from "../chunk-GK3TSZ4S.js";
44
44
  import {
45
45
  AnchorSessionClient,
46
46
  CHANNEL_REGISTRY,
@@ -71,7 +71,7 @@ import {
71
71
  requiredMcpWildcard,
72
72
  resolveChannels,
73
73
  serializeManifestForSlackCli
74
- } from "../chunk-SMHHGXI5.js";
74
+ } from "../chunk-LNPJI2AE.js";
75
75
  import "../chunk-XWVM4KPK.js";
76
76
 
77
77
  // src/bin/agt.ts
@@ -4830,7 +4830,7 @@ import { execFileSync, execSync } from "child_process";
4830
4830
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4831
4831
  import chalk18 from "chalk";
4832
4832
  import ora16 from "ora";
4833
- var cliVersion = true ? "0.28.506" : "dev";
4833
+ var cliVersion = true ? "0.28.508" : "dev";
4834
4834
  async function fetchLatestVersion() {
4835
4835
  const host2 = getHost();
4836
4836
  if (!host2) return null;
@@ -6002,7 +6002,7 @@ function handleError(err) {
6002
6002
  }
6003
6003
 
6004
6004
  // src/bin/agt.ts
6005
- var cliVersion2 = true ? "0.28.506" : "dev";
6005
+ var cliVersion2 = true ? "0.28.508" : "dev";
6006
6006
  var program = new Command();
6007
6007
  program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
6008
6008
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -43,7 +43,7 @@ import {
43
43
  resolveConnectivityProbe,
44
44
  worseConnectivityOutcome,
45
45
  wrapScheduledTaskPrompt
46
- } from "./chunk-SMHHGXI5.js";
46
+ } from "./chunk-LNPJI2AE.js";
47
47
  import {
48
48
  parsePsRows
49
49
  } from "./chunk-XWVM4KPK.js";
@@ -665,6 +665,228 @@ function decryptIntegrationCredentials(credentials) {
665
665
  return out;
666
666
  }
667
667
 
668
+ // ../../packages/core/dist/provisioning/github-broker-credentials.js
669
+ var GITHUB_BROKER_BIN_DIR = ".claude/agt-bin";
670
+ var GIT_CREDENTIAL_HELPER_BASENAME = "git-credential-agt-github";
671
+ var GH_SHIM_BASENAME = "gh";
672
+ var GITHUB_CREDENTIAL_PATH = "/host/agent-integrations/github/credential";
673
+ var BROKER_SCRIPT_MODE = 448;
674
+ function buildGitCredentialEnv(helperPath) {
675
+ return {
676
+ GIT_CONFIG_COUNT: "2",
677
+ GIT_CONFIG_KEY_0: "credential.https://github.com.helper",
678
+ GIT_CONFIG_VALUE_0: "",
679
+ GIT_CONFIG_KEY_1: "credential.https://github.com.helper",
680
+ GIT_CONFIG_VALUE_1: helperPath,
681
+ GIT_TERMINAL_PROMPT: "0"
682
+ };
683
+ }
684
+ var GITHUB_BROKER_ENV_KEYS = Object.keys(buildGitCredentialEnv(""));
685
+ var TOKEN_RESOLVER_PRELUDE = `
686
+ const AGT_HOST = (process.env.AGT_HOST || '').replace(/\\/+$/, '');
687
+ const AGT_API_KEY = process.env.AGT_API_KEY || '';
688
+ const AGT_AGENT_ID = process.env.AGT_AGENT_ID || '';
689
+
690
+ /**
691
+ * Every failure exits through here, so an operator always gets a sentence that
692
+ * names the credential fetch as the failing step. A bare 401 from GitHub sends
693
+ * people auditing App permissions; "broker credential fetch failed: 503" sends
694
+ * them at the API. Constraint D of ENG-8344.
695
+ */
696
+ function fail(reason) {
697
+ process.stderr.write(
698
+ 'augmented: GitHub credential fetch failed: ' + reason + '\\n' +
699
+ 'augmented: the token is fetched per use from ' + (AGT_HOST || '<AGT_HOST unset>') +
700
+ '${GITHUB_CREDENTIAL_PATH}' + ' (ENG-8344). This is NOT a GitHub permissions problem.\\n',
701
+ );
702
+ process.exit(1);
703
+ }
704
+
705
+ async function postJson(url, body, headers) {
706
+ let res;
707
+ try {
708
+ res = await fetch(url, {
709
+ method: 'POST',
710
+ headers: Object.assign({ 'Content-Type': 'application/json' }, headers || {}),
711
+ body: JSON.stringify(body),
712
+ signal: AbortSignal.timeout(15000),
713
+ });
714
+ } catch (err) {
715
+ throw new Error('cannot reach ' + url + ' (' + (err && err.message ? err.message : String(err)) + ')');
716
+ }
717
+ const text = await res.text().catch(() => '');
718
+ if (!res.ok) {
719
+ let detail = text.slice(0, 300);
720
+ try {
721
+ const parsed = JSON.parse(text);
722
+ if (parsed && parsed.error) detail = String(parsed.error);
723
+ } catch { /* keep the raw body */ }
724
+ throw new Error(url + ' returned HTTP ' + res.status + (detail ? ': ' + detail : ''));
725
+ }
726
+ try {
727
+ return JSON.parse(text);
728
+ } catch {
729
+ throw new Error(url + ' returned a non-JSON body');
730
+ }
731
+ }
732
+
733
+ async function resolveToken() {
734
+ if (!AGT_HOST) fail('AGT_HOST is not set in this process environment');
735
+ if (!AGT_API_KEY) fail('AGT_API_KEY is not set in this process environment');
736
+ if (!AGT_AGENT_ID) fail('AGT_AGENT_ID is not set in this process environment');
737
+
738
+ let jwt;
739
+ try {
740
+ const exchanged = await postJson(AGT_HOST + '/host/exchange', { host_key: AGT_API_KEY });
741
+ jwt = exchanged && exchanged.token;
742
+ } catch (err) {
743
+ fail('host key exchange failed - ' + err.message);
744
+ }
745
+ if (!jwt) fail('host key exchange returned no token');
746
+
747
+ let credential;
748
+ try {
749
+ credential = await postJson(
750
+ AGT_HOST + '${GITHUB_CREDENTIAL_PATH}',
751
+ { agent_id: AGT_AGENT_ID },
752
+ { Authorization: 'Bearer ' + jwt },
753
+ );
754
+ } catch (err) {
755
+ fail('broker credential fetch failed - ' + err.message);
756
+ }
757
+ const token = credential && credential.access_token;
758
+ if (typeof token !== 'string' || token === '') {
759
+ fail('the broker returned no access_token for the github integration (is it still connected?)');
760
+ }
761
+ return token;
762
+ }
763
+ `;
764
+ var GENERATED_BANNER = `#!/usr/bin/env node
765
+ // Auto-generated by Augmented (ENG-8344) \u2014 do not edit.
766
+ // Canonical source: packages/core/src/provisioning/github-broker-credentials.ts
767
+ `;
768
+ function renderGitCredentialHelper() {
769
+ return `${GENERATED_BANNER}${TOKEN_RESOLVER_PRELUDE}
770
+ function readStdin() {
771
+ return new Promise((resolve) => {
772
+ let buf = '';
773
+ process.stdin.setEncoding('utf8');
774
+ process.stdin.on('data', (chunk) => { buf += chunk; });
775
+ process.stdin.on('end', () => resolve(buf));
776
+ process.stdin.on('error', () => resolve(buf));
777
+ });
778
+ }
779
+
780
+ function parseCredentialRequest(input) {
781
+ const out = {};
782
+ for (const line of String(input).split('\\n')) {
783
+ if (line === '') continue;
784
+ const eq = line.indexOf('=');
785
+ if (eq <= 0) continue;
786
+ out[line.slice(0, eq)] = line.slice(eq + 1);
787
+ }
788
+ return out;
789
+ }
790
+
791
+ async function main() {
792
+ const operation = process.argv[2] || '';
793
+ // Nothing is persisted, so there is nothing to store or erase. Exit clean so
794
+ // a successful push does not print a helper error on the way out.
795
+ if (operation !== 'get') process.exit(0);
796
+
797
+ const request = parseCredentialRequest(await readStdin());
798
+
799
+ // Only ever answer for github.com over https. Any other host gets silence,
800
+ // which git treats as "this helper has no credential" and falls through to
801
+ // the next one - never a GitHub token handed to an unrelated server.
802
+ const host = request.host || '';
803
+ const protocol = request.protocol || '';
804
+ if (host !== 'github.com' || (protocol && protocol !== 'https')) process.exit(0);
805
+
806
+ const token = await resolveToken();
807
+ // x-access-token is the username GitHub expects for an App installation token.
808
+ process.stdout.write(
809
+ 'protocol=https\\n' +
810
+ 'host=github.com\\n' +
811
+ 'username=x-access-token\\n' +
812
+ 'password=' + token + '\\n' +
813
+ '\\n',
814
+ );
815
+ }
816
+
817
+ main().catch((err) => fail(err && err.message ? err.message : String(err)));
818
+ `;
819
+ }
820
+ function renderGhShim() {
821
+ return `${GENERATED_BANNER}${TOKEN_RESOLVER_PRELUDE}
822
+ const { spawnSync } = require('node:child_process');
823
+ const { accessSync, constants, realpathSync } = require('node:fs');
824
+ const { join, delimiter } = require('node:path');
825
+ const { constants: osConstants } = require('node:os');
826
+ const signals = osConstants.signals;
827
+
828
+ const SELF = (() => {
829
+ try { return realpathSync(__filename); } catch { return __filename; }
830
+ })();
831
+
832
+ /**
833
+ * First executable named 'gh' on PATH that is NOT this shim. Skipping by
834
+ * resolved path (not by directory string) means a symlinked or relocated bin
835
+ * dir cannot trick the search into re-entering the shim.
836
+ */
837
+ function findRealGh() {
838
+ for (const dir of (process.env.PATH || '').split(delimiter)) {
839
+ if (!dir) continue;
840
+ const candidate = join(dir, 'gh');
841
+ let resolved;
842
+ try {
843
+ accessSync(candidate, constants.X_OK);
844
+ resolved = realpathSync(candidate);
845
+ } catch { continue; }
846
+ if (resolved === SELF) continue;
847
+ return candidate;
848
+ }
849
+ return null;
850
+ }
851
+
852
+ async function main() {
853
+ const realGh = findRealGh();
854
+ if (!realGh) {
855
+ process.stderr.write(
856
+ 'augmented: the real gh binary is not on PATH (only the Augmented shim is). ' +
857
+ 'Install gh, or unset the broker credential path.\\n',
858
+ );
859
+ process.exit(127);
860
+ }
861
+
862
+ const token = await resolveToken();
863
+ // Token lives ONLY in this child's environment, for this one command.
864
+ const env = Object.assign({}, process.env, {
865
+ GH_TOKEN: token,
866
+ GITHUB_TOKEN: token,
867
+ });
868
+ const result = spawnSync(realGh, process.argv.slice(2), { stdio: 'inherit', env });
869
+ if (result.error) {
870
+ process.stderr.write('augmented: failed to run ' + realGh + ': ' + result.error.message + '\\n');
871
+ process.exit(126);
872
+ }
873
+ // Report a signal death as the shell convention 128+n, with n the REAL signal
874
+ // number from os.constants.signals. \`result.signal\` is a name ('SIGINT'), not
875
+ // a number, so a truthiness check would collapse every signal to 129 and a
876
+ // Ctrl-C would report 129 instead of 130 - wrong in exactly the case a caller
877
+ // inspects the code to tell "interrupted" from "failed". Unknown name falls
878
+ // back to 128, which reads as "died on a signal we could not name".
879
+ if (result.status === null) {
880
+ const number = signals[result.signal];
881
+ process.exit(128 + (typeof number === 'number' ? number : 0));
882
+ }
883
+ process.exit(result.status);
884
+ }
885
+
886
+ main().catch((err) => fail(err && err.message ? err.message : String(err)));
887
+ `;
888
+ }
889
+
668
890
  // ../../packages/core/dist/provisioning/frameworks/claudecode/index.js
669
891
  var VALID_CODE_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
670
892
  var SECRET_FILE_MODE = 384;
@@ -934,6 +1156,21 @@ function migrateLegacyClaudecodeDir(codeName, log) {
934
1156
  emit(`[migrate] '${codeName}': migration failed \u2014 leaving legacy dir in place: ${err.message}`);
935
1157
  }
936
1158
  }
1159
+ function syncGitHubBrokerCredentialTooling(projectDir, enabled) {
1160
+ const binDir = join2(projectDir, GITHUB_BROKER_BIN_DIR);
1161
+ if (!enabled) {
1162
+ rmSync(binDir, { recursive: true, force: true });
1163
+ return {};
1164
+ }
1165
+ const helperPath = join2(binDir, GIT_CREDENTIAL_HELPER_BASENAME);
1166
+ const shimPath = join2(binDir, GH_SHIM_BASENAME);
1167
+ mkdirSync2(binDir, { recursive: true });
1168
+ writeFileSync3(helperPath, renderGitCredentialHelper(), { mode: BROKER_SCRIPT_MODE });
1169
+ chmodSync3(helperPath, BROKER_SCRIPT_MODE);
1170
+ writeFileSync3(shimPath, renderGhShim(), { mode: BROKER_SCRIPT_MODE });
1171
+ chmodSync3(shimPath, BROKER_SCRIPT_MODE);
1172
+ return buildGitCredentialEnv(helperPath);
1173
+ }
937
1174
  function getProjectDir(codeName) {
938
1175
  return join2(getAgentDir(codeName), "project");
939
1176
  }
@@ -4310,6 +4547,8 @@ ${sections}`
4310
4547
  const unscopedPrefix = remoteMcpEnvPrefix(integration.definition_id, null);
4311
4548
  const creds = integration.credentials;
4312
4549
  const def = INTEGRATION_REGISTRY.find((d) => d.id === integration.definition_id);
4550
+ if (integration.credentialDelivery === "broker")
4551
+ continue;
4313
4552
  let token;
4314
4553
  if (integration.auth_type === "oauth2" || integration.auth_type === "github_app") {
4315
4554
  token = creds.access_token;
@@ -4357,6 +4596,7 @@ ${sections}`
4357
4596
  envUpdates[scoped] = value;
4358
4597
  }
4359
4598
  }
4599
+ Object.assign(envUpdates, syncGitHubBrokerCredentialTooling(getProjectDir(codeName), decryptedIntegrations.some((i) => i.definition_id === "github" && i.credentialDelivery === "broker")));
4360
4600
  writeEnvIntegrationsForAgent(codeName, {
4361
4601
  mode: "replace-preserving",
4362
4602
  updates: envUpdates
@@ -5062,7 +5302,7 @@ function exchangeFailureKind(err) {
5062
5302
  }
5063
5303
 
5064
5304
  // src/lib/api-client.ts
5065
- var agtCliVersion = true ? "0.28.506" : "dev";
5305
+ var agtCliVersion = true ? "0.28.508" : "dev";
5066
5306
  var lastConfigHash = null;
5067
5307
  function setConfigHash(hash) {
5068
5308
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -8368,4 +8608,4 @@ export {
8368
8608
  managerInstallSystemUnitCommand,
8369
8609
  managerUninstallSystemUnitCommand
8370
8610
  };
8371
- //# sourceMappingURL=chunk-43UIRCO7.js.map
8611
+ //# sourceMappingURL=chunk-GK3TSZ4S.js.map