@craftsamo/agent-github 0.1.0 → 0.2.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/dist/mcp.js CHANGED
@@ -3911,50 +3911,50 @@ var require_fast_uri = __commonJS({
3911
3911
  schemelessOptions.skipEscape = true;
3912
3912
  return serialize(resolved, schemelessOptions);
3913
3913
  }
3914
- function resolveComponent(base, relative, options, skipNormalization) {
3914
+ function resolveComponent(base, relative2, options, skipNormalization) {
3915
3915
  const target = {};
3916
3916
  if (!skipNormalization) {
3917
3917
  base = parse3(serialize(base, options), options);
3918
- relative = parse3(serialize(relative, options), options);
3918
+ relative2 = parse3(serialize(relative2, options), options);
3919
3919
  }
3920
3920
  options = options || {};
3921
- if (!options.tolerant && relative.scheme) {
3922
- target.scheme = relative.scheme;
3923
- target.userinfo = relative.userinfo;
3924
- target.host = relative.host;
3925
- target.port = relative.port;
3926
- target.path = removeDotSegments(relative.path || "");
3927
- target.query = relative.query;
3921
+ if (!options.tolerant && relative2.scheme) {
3922
+ target.scheme = relative2.scheme;
3923
+ target.userinfo = relative2.userinfo;
3924
+ target.host = relative2.host;
3925
+ target.port = relative2.port;
3926
+ target.path = removeDotSegments(relative2.path || "");
3927
+ target.query = relative2.query;
3928
3928
  } else {
3929
- if (relative.userinfo !== void 0 || relative.host !== void 0 || relative.port !== void 0) {
3930
- target.userinfo = relative.userinfo;
3931
- target.host = relative.host;
3932
- target.port = relative.port;
3933
- target.path = removeDotSegments(relative.path || "");
3934
- target.query = relative.query;
3929
+ if (relative2.userinfo !== void 0 || relative2.host !== void 0 || relative2.port !== void 0) {
3930
+ target.userinfo = relative2.userinfo;
3931
+ target.host = relative2.host;
3932
+ target.port = relative2.port;
3933
+ target.path = removeDotSegments(relative2.path || "");
3934
+ target.query = relative2.query;
3935
3935
  } else {
3936
- if (!relative.path) {
3936
+ if (!relative2.path) {
3937
3937
  target.path = base.path;
3938
- if (relative.query !== void 0) {
3939
- target.query = relative.query;
3938
+ if (relative2.query !== void 0) {
3939
+ target.query = relative2.query;
3940
3940
  } else {
3941
3941
  target.query = base.query;
3942
3942
  }
3943
3943
  } else {
3944
- if (relative.path[0] === "/") {
3945
- target.path = removeDotSegments(relative.path);
3944
+ if (relative2.path[0] === "/") {
3945
+ target.path = removeDotSegments(relative2.path);
3946
3946
  } else {
3947
3947
  const baseHasAuthority = base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0;
3948
3948
  if (baseHasAuthority && !base.path) {
3949
- target.path = "/" + relative.path;
3949
+ target.path = "/" + relative2.path;
3950
3950
  } else if (!base.path) {
3951
- target.path = relative.path;
3951
+ target.path = relative2.path;
3952
3952
  } else {
3953
- target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative.path;
3953
+ target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative2.path;
3954
3954
  }
3955
3955
  target.path = base.scheme === void 0 && !baseHasAuthority && target.path[0] !== "/" ? removeDotSegmentsRelative(target.path) : removeDotSegments(target.path);
3956
3956
  }
3957
- target.query = relative.query;
3957
+ target.query = relative2.query;
3958
3958
  }
3959
3959
  target.userinfo = base.userinfo;
3960
3960
  target.host = base.host;
@@ -3962,7 +3962,7 @@ var require_fast_uri = __commonJS({
3962
3962
  }
3963
3963
  target.scheme = base.scheme;
3964
3964
  }
3965
- target.fragment = relative.fragment;
3965
+ target.fragment = relative2.fragment;
3966
3966
  return target;
3967
3967
  }
3968
3968
  function equal(uriA, uriB, options) {
@@ -28956,6 +28956,8 @@ async function paginate(query, vars, pick2, options) {
28956
28956
  }
28957
28957
 
28958
28958
  // src/core/refs.ts
28959
+ import { realpath } from "node:fs/promises";
28960
+ import { isAbsolute, relative, sep } from "node:path";
28959
28961
  var DEFAULT_HOST = "github.com";
28960
28962
  var SSH_ALIAS_HOST = "ssh.github.com";
28961
28963
  var GIT_CONFIG_ENV = ["GIT_CONFIG_GLOBAL", "GIT_CONFIG_SYSTEM", "GIT_CONFIG_NOSYSTEM"];
@@ -29039,11 +29041,25 @@ function gitEnv() {
29039
29041
  }
29040
29042
  return { ...env, GIT_TERMINAL_PROMPT: "0" };
29041
29043
  }
29042
- async function repoFromOrigin(cwd, signal) {
29044
+ async function isWithin(dir, root) {
29045
+ try {
29046
+ const path = relative(await realpath(root), await realpath(dir));
29047
+ return path === "" || !(path === ".." || path.startsWith(`..${sep}`) || isAbsolute(path));
29048
+ } catch {
29049
+ return false;
29050
+ }
29051
+ }
29052
+ async function repoFromOrigin(cwd, signal, ownDir) {
29043
29053
  const env = gitEnv();
29044
- const unresolved = (why) => invalid(
29045
- `Cannot tell which repository to use: ${why}. Run the call inside a clone of a GitHub repository, or pass \`repo\` as owner/name.`
29054
+ const unresolved = (why, advice = "") => invalid(
29055
+ `Cannot tell which repository to use: ${why}. Run the call inside a clone of a GitHub repository, or pass \`repo\` as owner/name.${advice}`
29046
29056
  );
29057
+ if (ownDir !== void 0 && await isWithin(cwd, ownDir)) {
29058
+ throw unresolved(
29059
+ `${cwd} is where these tools are installed, not a project`,
29060
+ " An issue can be given as `owner/repo#N`."
29061
+ );
29062
+ }
29047
29063
  let result;
29048
29064
  try {
29049
29065
  result = await exec(["git", "remote", "get-url", "origin"], { cwd, env, signal });
@@ -29058,7 +29074,10 @@ async function repoFromOrigin(cwd, signal) {
29058
29074
  return repo;
29059
29075
  }
29060
29076
  async function resolveRepo(repo, ctx) {
29061
- return repo === void 0 || repo.trim() === "" ? repoFromOrigin(ctx.cwd, ctx.signal) : parseRepo(repo);
29077
+ return repo === void 0 || repo.trim() === "" ? repoFromOrigin(ctx.cwd, ctx.signal, ctx.ownDir) : parseRepo(repo);
29078
+ }
29079
+ function isBareNumber(ref) {
29080
+ return BARE_NUMBER_PATTERN.test(ref.trim());
29062
29081
  }
29063
29082
  function parseNumber(digits, ref) {
29064
29083
  const number4 = Number.parseInt(digits, 10);
@@ -29128,6 +29147,10 @@ function defineTool(spec) {
29128
29147
  if (!(spec.output instanceof external_exports.ZodObject)) {
29129
29148
  throw new Error(`Tool "${spec.id}" must have an object output schema, since a result is an object.`);
29130
29149
  }
29150
+ const unknownTarget = Object.keys(spec.targets ?? {}).find((name) => !Object.hasOwn(spec.input.shape, name));
29151
+ if (unknownTarget !== void 0) {
29152
+ throw new Error(`Tool "${spec.id}" declares the target "${unknownTarget}", which is not one of its arguments.`);
29153
+ }
29131
29154
  return spec;
29132
29155
  }
29133
29156
  var CLASS_HINTS = {
@@ -29233,6 +29256,13 @@ var StepErrors = class {
29233
29256
  }
29234
29257
  };
29235
29258
 
29259
+ // src/entry/package-root.ts
29260
+ import { dirname } from "node:path";
29261
+ import { fileURLToPath } from "node:url";
29262
+ function packageRoot(bundleUrl) {
29263
+ return dirname(dirname(fileURLToPath(bundleUrl)));
29264
+ }
29265
+
29236
29266
  // src/entry/settings.ts
29237
29267
  var CONFIRM_MODES = ["harness", "elicitation"];
29238
29268
  var ALL_TOOLSETS = "all";
@@ -29758,10 +29788,9 @@ async function readSubIssues(parent, ctx) {
29758
29788
  }
29759
29789
 
29760
29790
  // src/core/github/issue-refs.ts
29761
- var BARE_NUMBER = /^#?\d+$/;
29762
29791
  async function resolveRelatedIssue(ref, target, ctx) {
29763
29792
  const text = ref.trim();
29764
- return parseNumberRef(text, BARE_NUMBER.test(text) ? target.full : void 0, ctx, { accept: "issue" });
29793
+ return parseNumberRef(text, isBareNumber(text) ? target.full : void 0, ctx, { accept: "issue" });
29765
29794
  }
29766
29795
  function issueLabel(issue2) {
29767
29796
  return `${issue2.repo.full}#${issue2.number}`;
@@ -29773,6 +29802,7 @@ function ghIssueRef(issue2, target) {
29773
29802
  // src/core/issues/write-support.ts
29774
29803
  var REPO_DESCRIPTION = "owner/name; defaults to the working tree's repository (its origin). Used for a bare number.";
29775
29804
  var ISSUE_DESCRIPTION = "The issue, as 12, #12, owner/repo#12 or its URL.";
29805
+ var ISSUE_TARGETS = { issue: "issue", repo: "repo" };
29776
29806
  var LIST_SYNTAX = /[,"\r\n]/;
29777
29807
  var URL_LINE = /^https?:\/\/\S+$/;
29778
29808
  function invalid2(message) {
@@ -29842,6 +29872,7 @@ var issueClose = defineTool({
29842
29872
  ].join(" "),
29843
29873
  toolset: "issues",
29844
29874
  class: "overwrite",
29875
+ targets: ISSUE_TARGETS,
29845
29876
  input: input2,
29846
29877
  output: output2,
29847
29878
  async execute(args, ctx) {
@@ -29898,6 +29929,7 @@ var issueComment = defineTool({
29898
29929
  ].join(" "),
29899
29930
  toolset: "issues",
29900
29931
  class: "add",
29932
+ targets: ISSUE_TARGETS,
29901
29933
  input: input3,
29902
29934
  output: output3,
29903
29935
  async execute(args, ctx) {
@@ -30015,6 +30047,7 @@ var issueCreate = defineTool({
30015
30047
  ].join(" "),
30016
30048
  toolset: "issues",
30017
30049
  class: "add",
30050
+ targets: { repo: "repo", parent: "issue", blocked_by: "issues" },
30018
30051
  input: input4,
30019
30052
  output: output4,
30020
30053
  async execute(args, ctx) {
@@ -30162,6 +30195,7 @@ var issueDevelop = defineTool({
30162
30195
  ].join(" "),
30163
30196
  toolset: "issues",
30164
30197
  class: "idempotent",
30198
+ targets: { ...ISSUE_TARGETS, branch_repo: "repo" },
30165
30199
  input: input5,
30166
30200
  output: output5,
30167
30201
  async execute(args, ctx) {
@@ -30309,6 +30343,7 @@ var issueEdit = defineTool({
30309
30343
  ].join(" "),
30310
30344
  toolset: "issues",
30311
30345
  class: "overwrite",
30346
+ targets: ISSUE_TARGETS,
30312
30347
  input: input6,
30313
30348
  output: output6,
30314
30349
  async execute(args, ctx) {
@@ -30667,6 +30702,16 @@ var issueRelate = defineTool({
30667
30702
  ].join(" "),
30668
30703
  toolset: "issues",
30669
30704
  class: "idempotent",
30705
+ targets: {
30706
+ ...ISSUE_TARGETS,
30707
+ parent: "issue",
30708
+ add_sub_issues: "issues",
30709
+ remove_sub_issues: "issues",
30710
+ add_blocked_by: "issues",
30711
+ remove_blocked_by: "issues",
30712
+ add_blocking: "issues",
30713
+ remove_blocking: "issues"
30714
+ },
30670
30715
  input: input8,
30671
30716
  output: output8,
30672
30717
  async execute(args, ctx) {
@@ -30765,6 +30810,7 @@ var issueReopen = defineTool({
30765
30810
  ].join(" "),
30766
30811
  toolset: "issues",
30767
30812
  class: "overwrite",
30813
+ targets: ISSUE_TARGETS,
30768
30814
  input: input9,
30769
30815
  output: output9,
30770
30816
  async execute(args, ctx) {
@@ -32582,7 +32628,7 @@ function elicitationConfirm(server, signal) {
32582
32628
 
32583
32629
  // src/mcp/roots.ts
32584
32630
  import { statSync } from "node:fs";
32585
- import { fileURLToPath } from "node:url";
32631
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
32586
32632
  var FILE_URI_PROTOCOL = "file:";
32587
32633
  async function isInsideWorkTree(dir, signal) {
32588
32634
  try {
@@ -32597,21 +32643,22 @@ function localDirectory(uri) {
32597
32643
  try {
32598
32644
  const url2 = new URL(uri);
32599
32645
  if (url2.protocol !== FILE_URI_PROTOCOL) return void 0;
32600
- const dir = fileURLToPath(url2);
32646
+ const dir = fileURLToPath2(url2);
32601
32647
  return statSync(dir, { throwIfNoEntry: false })?.isDirectory() ? dir : void 0;
32602
32648
  } catch {
32603
32649
  return void 0;
32604
32650
  }
32605
32651
  }
32606
- async function firstGitRoot(server, signal) {
32652
+ async function firstGitRoot(server, ownDir, signal) {
32607
32653
  const { roots } = await server.listRoots(void 0, { signal });
32608
32654
  for (const root of roots) {
32609
32655
  const dir = localDirectory(root.uri);
32610
- if (dir !== void 0 && await isInsideWorkTree(dir, signal)) return dir;
32656
+ if (dir === void 0 || ownDir !== void 0 && await isWithin(dir, ownDir)) continue;
32657
+ if (await isInsideWorkTree(dir, signal)) return dir;
32611
32658
  }
32612
32659
  return void 0;
32613
32660
  }
32614
- function createWorkingDirResolver(server, fallback) {
32661
+ function createWorkingDirResolver(server, fallback, ownDir) {
32615
32662
  let cached2;
32616
32663
  let generation = 0;
32617
32664
  server.setNotificationHandler(RootsListChangedNotificationSchema, () => {
@@ -32624,7 +32671,7 @@ function createWorkingDirResolver(server, fallback) {
32624
32671
  const started = generation;
32625
32672
  let dir;
32626
32673
  try {
32627
- dir = await firstGitRoot(server, signal) ?? fallback();
32674
+ dir = await firstGitRoot(server, ownDir, signal) ?? fallback();
32628
32675
  } catch (error62) {
32629
32676
  if (signal?.aborted || isAbortError(error62)) throw error62;
32630
32677
  return fallback();
@@ -32659,7 +32706,7 @@ function createServer(specs, settings, options = {}) {
32659
32706
  { name: SERVER_NAME, version: options.version ?? DEFAULT_VERSION },
32660
32707
  { capabilities: { tools: {} } }
32661
32708
  );
32662
- const workingDir = createWorkingDirResolver(server, options.cwd ?? (() => process.cwd()));
32709
+ const workingDir = createWorkingDirResolver(server, options.cwd ?? (() => process.cwd()), options.ownDir);
32663
32710
  const selected = new Map(selectTools(specs, settings).map((spec) => [spec.id, spec]));
32664
32711
  const tools = [...selected.values()].map(describeTool);
32665
32712
  server.setRequestHandler(ListToolsRequestSchema, () => ({ tools }));
@@ -32670,6 +32717,7 @@ function createServer(specs, settings, options = {}) {
32670
32717
  const confirm = settings.confirm === "elicitation" ? elicitationConfirm(server, extra.signal) : void 0;
32671
32718
  const ctx = {
32672
32719
  cwd: await workingDir(extra.signal),
32720
+ ownDir: options.ownDir,
32673
32721
  signal: extra.signal,
32674
32722
  ...confirm && { confirm }
32675
32723
  };
@@ -32694,7 +32742,8 @@ async function main() {
32694
32742
  try {
32695
32743
  const settings = parseSettings(process.argv.slice(2), process.env);
32696
32744
  server = createServer(ALL_TOOLS, settings, {
32697
- version: true ? "0.1.0" : void 0
32745
+ ownDir: packageRoot(import.meta.url),
32746
+ version: true ? "0.2.0" : void 0
32698
32747
  });
32699
32748
  } catch (error62) {
32700
32749
  if (!isToolError(error62)) throw error62;