@sentry/junior-github 0.167.0 → 0.169.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/index.js +36 -20
- package/dist/tools/clone-repository.d.ts +2 -3
- package/package.json +2 -2
- package/skills/github-code/SKILL.md +2 -2
package/dist/index.js
CHANGED
|
@@ -751,12 +751,14 @@ var inputSchema = z.object({
|
|
|
751
751
|
}
|
|
752
752
|
).describe(
|
|
753
753
|
"Optional destination directory under the sandbox root. Defaults to repos/{name}."
|
|
754
|
-
).optional()
|
|
754
|
+
).optional(),
|
|
755
|
+
allowAdHoc: z.boolean().optional().describe(
|
|
756
|
+
"Set true to keep an intentional ad-hoc checkout when matching Workspaces exist. Prefer switchWorkspace; the checkout is already present after a successful switch."
|
|
757
|
+
)
|
|
755
758
|
}).strict();
|
|
756
759
|
var cloneSchema = z.object({
|
|
757
760
|
path: z.string(),
|
|
758
|
-
repo: z.string()
|
|
759
|
-
workspaces: z.array(z.string())
|
|
761
|
+
repo: z.string()
|
|
760
762
|
});
|
|
761
763
|
var outputSchema = pluginToolOutputSchema.extend({
|
|
762
764
|
target: z.literal("cloneRepository"),
|
|
@@ -769,6 +771,17 @@ function parseRepo(value) {
|
|
|
769
771
|
}
|
|
770
772
|
return { owner: parts[0], name: parts[1] };
|
|
771
773
|
}
|
|
774
|
+
function workspaceRequiredError(repoId, workspaces) {
|
|
775
|
+
const names = workspaces.map((name) => `"${name}"`).join(", ");
|
|
776
|
+
if (workspaces.length === 1) {
|
|
777
|
+
return new PluginToolInputError(
|
|
778
|
+
`Repository ${repoId} is part of Workspace ${names}. Call switchWorkspace with that name; the checkout is already present after the switch. Pass allowAdHoc=true only for an intentional ad-hoc checkout.`
|
|
779
|
+
);
|
|
780
|
+
}
|
|
781
|
+
return new PluginToolInputError(
|
|
782
|
+
`Repository ${repoId} is part of Workspaces ${names}. Call switchWorkspace with one of those names; the checkout is already present after the switch. Pass allowAdHoc=true only for an intentional ad-hoc checkout.`
|
|
783
|
+
);
|
|
784
|
+
}
|
|
772
785
|
function defaultDirectory(repoName) {
|
|
773
786
|
return `repos/${repoName}`;
|
|
774
787
|
}
|
|
@@ -808,16 +821,33 @@ function createGitHubCloneRepositoryTool(ctx) {
|
|
|
808
821
|
openWorldHint: true,
|
|
809
822
|
readOnlyHint: true
|
|
810
823
|
},
|
|
811
|
-
description: "Clone a GitHub repository into the sandbox
|
|
824
|
+
description: "Clone a GitHub repository into the sandbox as an ad-hoc checkout. The destination must not already exist. When matching Workspaces exist this is a tool input error: call switchWorkspace instead, or pass allowAdHoc=true for an intentional ad-hoc checkout.",
|
|
812
825
|
describeProposal(input) {
|
|
813
826
|
const directory = typeof input.directory === "string" && input.directory.length > 0 ? input.directory : void 0;
|
|
814
|
-
|
|
827
|
+
const adHoc = input.allowAdHoc === true ? " as an intentional ad-hoc checkout" : "";
|
|
828
|
+
return directory ? `Shallow-clone ${input.repo} into the local sandbox at ${directory}${adHoc} for inspection (no GitHub mutation).` : `Shallow-clone ${input.repo} into the local sandbox${adHoc} for inspection (no GitHub mutation).`;
|
|
815
829
|
},
|
|
816
830
|
executionMode: "sequential",
|
|
817
831
|
inputSchema,
|
|
818
832
|
outputSchema,
|
|
819
833
|
async execute(input, options) {
|
|
820
834
|
const repo = parseRepo(input.repo);
|
|
835
|
+
const repoId = `${repo.owner}/${repo.name}`;
|
|
836
|
+
let workspaces = [];
|
|
837
|
+
try {
|
|
838
|
+
workspaces = await ctx.workspaces.findByRepository({
|
|
839
|
+
provider: "github",
|
|
840
|
+
repo: repoId
|
|
841
|
+
});
|
|
842
|
+
} catch (error) {
|
|
843
|
+
ctx.log.error("github.clone.workspaces_lookup.failed", {
|
|
844
|
+
repo: repoId,
|
|
845
|
+
error: error instanceof Error ? error.message : String(error)
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
if (workspaces.length > 0 && input.allowAdHoc !== true) {
|
|
849
|
+
throw workspaceRequiredError(repoId, workspaces);
|
|
850
|
+
}
|
|
821
851
|
const directory = input.directory ?? defaultDirectory(repo.name);
|
|
822
852
|
const rootSegment = directory.split("/")[0] ?? directory;
|
|
823
853
|
if (isReservedSandboxDirectory(rootSegment)) {
|
|
@@ -874,21 +904,7 @@ function createGitHubCloneRepositoryTool(ctx) {
|
|
|
874
904
|
`GitHub repository clone failed: ${clone.stderr.trim() || `exit ${clone.exitCode}`}`
|
|
875
905
|
);
|
|
876
906
|
}
|
|
877
|
-
|
|
878
|
-
let workspaces = [];
|
|
879
|
-
try {
|
|
880
|
-
workspaces = await ctx.workspaces.findByRepository({
|
|
881
|
-
provider: "github",
|
|
882
|
-
repo: repoId
|
|
883
|
-
});
|
|
884
|
-
} catch (error) {
|
|
885
|
-
ctx.log.error("github.clone.workspaces_lookup.failed", {
|
|
886
|
-
repo: repoId,
|
|
887
|
-
error: error instanceof Error ? error.message : String(error)
|
|
888
|
-
});
|
|
889
|
-
}
|
|
890
|
-
const data = { repo: repoId, path, workspaces };
|
|
891
|
-
return { target: "cloneRepository", ...data };
|
|
907
|
+
return { target: "cloneRepository", repo: repoId, path };
|
|
892
908
|
}
|
|
893
909
|
});
|
|
894
910
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { type ToolRegistrationHookContext } from "@sentry/junior-plugin-api";
|
|
2
|
-
/** Clone one GitHub repository into the sandbox
|
|
2
|
+
/** Clone one GitHub repository into the sandbox as an ad-hoc checkout. */
|
|
3
3
|
export declare function createGitHubCloneRepositoryTool(ctx: ToolRegistrationHookContext): import("@sentry/junior-plugin-api").PluginToolDefinition<{
|
|
4
4
|
repo: string;
|
|
5
5
|
directory?: string | undefined;
|
|
6
|
+
allowAdHoc?: boolean | undefined;
|
|
6
7
|
}, {
|
|
7
8
|
[x: string]: unknown;
|
|
8
9
|
path: string;
|
|
9
10
|
repo: string;
|
|
10
|
-
workspaces: string[];
|
|
11
11
|
target: "cloneRepository";
|
|
12
12
|
truncated?: boolean | undefined;
|
|
13
13
|
continuation?: {
|
|
@@ -18,7 +18,6 @@ export declare function createGitHubCloneRepositoryTool(ctx: ToolRegistrationHoo
|
|
|
18
18
|
[x: string]: unknown;
|
|
19
19
|
path: string;
|
|
20
20
|
repo: string;
|
|
21
|
-
workspaces: string[];
|
|
22
21
|
target: "cloneRepository";
|
|
23
22
|
truncated?: boolean | undefined;
|
|
24
23
|
continuation?: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior-github",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.169.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@sinclair/typebox": "^0.34.49",
|
|
32
32
|
"drizzle-orm": "^0.45.2",
|
|
33
33
|
"zod": "^4.4.3",
|
|
34
|
-
"@sentry/junior-plugin-api": "0.
|
|
34
|
+
"@sentry/junior-plugin-api": "0.169.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/node": "^25.9.1",
|
|
@@ -23,7 +23,7 @@ Use `git` and `gh` for repository work. Use `github_createPullRequest`, not `gh
|
|
|
23
23
|
- Base conclusions on repository evidence. Do not claim a check ran unless it did.
|
|
24
24
|
- For Junior-owned pull requests, push the branch before creating the PR. The runtime supplies repository-scoped GitHub App credentials for both; try the operations before requesting remediation and never ask for a user token.
|
|
25
25
|
- Use `github_cloneRepository` instead of shelling out to `git clone` when a repository is not already available in the sandbox.
|
|
26
|
-
-
|
|
26
|
+
- If `github_cloneRepository` returns a tool input error about matching Workspaces, call `switchWorkspace`. The checkout is already present after a successful switch. Pass `allowAdHoc=true` only for an intentional ad-hoc checkout.
|
|
27
27
|
- A tool-routing denial requires the named tool; only an upstream denial justifies permission remediation.
|
|
28
28
|
- Stop for ambiguous targets, missing access, destructive operations, or unresolved upstream permission failures.
|
|
29
29
|
|
|
@@ -31,7 +31,7 @@ Use `git` and `gh` for repository work. Use `github_createPullRequest`, not `gh
|
|
|
31
31
|
|
|
32
32
|
### 1. Resolve and inspect
|
|
33
33
|
|
|
34
|
-
Identify the repo, checkout, default/current branches, worktree state, repo instructions, package manager, and relevant checks. Prefer an existing checkout; otherwise clone shallowly.
|
|
34
|
+
Identify the repo, checkout, default/current branches, worktree state, repo instructions, package manager, and relevant checks. Prefer an existing checkout or matching Workspace; otherwise clone shallowly. If clone returns a Workspace tool input error, switch Workspace instead of cloning again, or pass `allowAdHoc=true`.
|
|
35
35
|
|
|
36
36
|
A shallow clone is for fast inspection, not history rewriting. Before rebasing, merge-base analysis, blame/history work, or comparing against a base absent locally, fetch the needed refs and deepen incrementally. Use `--unshallow` only when bounded deepening is insufficient. Never use a force push to compensate for incomplete history.
|
|
37
37
|
|