mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-31 22:24:16 +01:00
Preview local git repo project workspace files
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
df1ab634f7
commit
50feeb312a
2 files changed
+47
-3
No files matched your search
@@ -58,6 +58,7 @@ async function seedGraph(db: Db, input: {
|
||||
targetProjectRoot?: string;
|
||||
executionRoot?: string | null;
|
||||
projectSourceType?: string;
|
||||
targetProjectSourceType?: string;
|
||||
}): Promise<TestGraph> {
|
||||
const suffix = crypto.randomUUID().slice(0, 8);
|
||||
const companyId = crypto.randomUUID();
|
||||
@@ -111,7 +112,7 @@ async function seedGraph(db: Db, input: {
|
||||
companyId,
|
||||
projectId: targetProjectId,
|
||||
name: "Target workspace",
|
||||
sourceType: "local_path",
|
||||
sourceType: input.targetProjectSourceType ?? "local_path",
|
||||
cwd: input.targetProjectRoot ?? input.projectRoot,
|
||||
isPrimary: true,
|
||||
},
|
||||
@@ -286,6 +287,48 @@ describeEmbeddedPostgres("workspace file resources", () => {
|
||||
expect(JSON.stringify(read?.details)).not.toContain(targetProjectRoot);
|
||||
});
|
||||
|
||||
it("reads explicit cross-project git_repo workspaces with a local checkout", async () => {
|
||||
const { root, projectRoot, targetProjectRoot, executionRoot } = await makeWorkspace();
|
||||
const graph = await seedGraph(db, {
|
||||
projectRoot,
|
||||
targetProjectRoot,
|
||||
executionRoot,
|
||||
targetProjectSourceType: "git_repo",
|
||||
});
|
||||
const readmePath = "content-os/cases/active/2026-06-06-pap-10199-bundled-skills/README.md";
|
||||
await fs.mkdir(path.join(targetProjectRoot, path.dirname(readmePath)), { recursive: true });
|
||||
await fs.writeFile(path.join(targetProjectRoot, readmePath), "# Bundled skills\n\nRendered from content project.\n", "utf8");
|
||||
|
||||
const app = createApp(db, {
|
||||
type: "board",
|
||||
userId: "board-user",
|
||||
companyIds: [graph.companyId],
|
||||
source: "session",
|
||||
isInstanceAdmin: false,
|
||||
});
|
||||
const res = await request(app)
|
||||
.get(`/api/issues/${graph.issueId}/file-resources/content`)
|
||||
.query({
|
||||
projectId: graph.targetProjectId,
|
||||
workspaceId: graph.targetProjectWorkspaceId,
|
||||
path: readmePath,
|
||||
});
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.body.resource).toMatchObject({
|
||||
workspaceKind: "project_workspace",
|
||||
workspaceId: graph.targetProjectWorkspaceId,
|
||||
projectId: graph.targetProjectId,
|
||||
projectName: "Target project",
|
||||
displayPath: `Target project / ${readmePath}`,
|
||||
provider: "git_repo",
|
||||
previewKind: "text",
|
||||
});
|
||||
expect(res.body.content.encoding).toBe("utf8");
|
||||
expect(res.body.content.data).toContain("# Bundled skills");
|
||||
expect(JSON.stringify(res.body)).not.toContain(root);
|
||||
});
|
||||
|
||||
it("denies explicit cross-company project workspaces", async () => {
|
||||
const { projectRoot, targetProjectRoot, executionRoot } = await makeWorkspace();
|
||||
const graph = await seedGraph(db, { projectRoot, targetProjectRoot, executionRoot });
|
||||
|
||||
@@ -27,6 +27,7 @@ const TEXT_SNIFF_BYTES = 4096;
|
||||
const MAX_LIST_DEPTH = 20;
|
||||
const GIT_STATUS_MAX_BUFFER_BYTES = 1024 * 1024;
|
||||
const execFileAsync = promisify(execFile);
|
||||
const LOCAL_PROJECT_WORKSPACE_SOURCE_TYPES = new Set(["local_path", "non_git_path", "git_repo", "git_worktree"]);
|
||||
|
||||
const DENIED_SEGMENTS = new Set([
|
||||
".git",
|
||||
@@ -315,9 +316,9 @@ function candidateFromProjectWorkspace(
|
||||
row: ProjectWorkspaceRow,
|
||||
project?: { id: string; name: string } | null,
|
||||
): WorkspaceCandidate {
|
||||
const provider = row.sourceType === "git_worktree" ? "git_worktree" : row.sourceType === "local_path" ? "local_fs" : row.sourceType;
|
||||
const provider = row.sourceType === "local_path" ? "local_fs" : row.sourceType;
|
||||
const rootPath = row.cwd ?? null;
|
||||
const remote = !["local_fs", "git_worktree"].includes(provider) || !rootPath;
|
||||
const remote = !LOCAL_PROJECT_WORKSPACE_SOURCE_TYPES.has(row.sourceType) || !rootPath;
|
||||
return {
|
||||
workspaceKind: "project_workspace",
|
||||
workspaceId: row.id,
|
||||
|
||||
Reference in new issue
Block a user