Merge pinned master into work folders base and reconcile migration 0277

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-09-12 18:26:16 -05:00
commit f5bbc84ee2
293 files changed
+115893 -1966

No files matched your search

+3 -2
View File
@@ -223,6 +223,7 @@ export const agentsApi = {
type: string,
data: {
adapterConfig: Record<string, unknown>;
aiConnection?: import("@paperclipai/shared").AiConnectionBinding;
agentId?: string;
testCredentials?: Record<string, string>;
environmentId?: string | null;
@@ -274,7 +275,7 @@ export const agentsApi = {
startAdapterAuthLogin: (
companyId: string,
type: string,
data: { environmentId: string; ttlSeconds?: number },
data: { environmentId: string; ttlSeconds?: number; aiConnection?: import("@paperclipai/shared").AiConnectionLoginIntent },
) =>
api.post<AdapterAuthSessionResponse>(
`/companies/${encodeURIComponent(companyId)}/adapters/${encodeURIComponent(type)}/login-sessions`,
@@ -317,7 +318,7 @@ export const agentsApi = {
),
startClaudeSetupTokenLogin: (
companyId: string,
data: { environmentId: string; overwrite?: ClaudeSetupTokenOverwrite },
data: { environmentId: string; overwrite?: ClaudeSetupTokenOverwrite; aiConnection?: import("@paperclipai/shared").AiConnectionLoginIntent },
) =>
api.post<ClaudeSetupTokenSessionOwnerResponse>(
`/companies/${encodeURIComponent(companyId)}/setup-token-login-sessions`,
+13
View File
@@ -0,0 +1,13 @@
import type { AiManagedConnectionSummary, CreateAiConnection, AiConnectionLoginIntent, LocalAiLoginAttempt, LocalAiLoginStatus } from "@paperclipai/shared";
import { api } from "./client";
export const aiConnectionsApi = {
startLocalLogin: (companyId: string, input: AiConnectionLoginIntent & { restart?: boolean }) => api.post<LocalAiLoginAttempt>(`/companies/${companyId}/ai-connections/local/attempts`, input),
checkLocalLogin: (companyId: string, input: AiConnectionLoginIntent & { localSessionId?: string }) => api.post<LocalAiLoginStatus>(`/companies/${companyId}/ai-connections/local/check`, input),
cancelLocalLogin: (companyId: string, sessionId: string) => api.delete(`/companies/${companyId}/ai-connections/local/attempts/${sessionId}`),
connectLocal: (companyId: string, input: AiConnectionLoginIntent & { localSessionId?: string }) => api.post<{ connectionId: string; grantId: string }>(`/companies/${companyId}/ai-connections/local`, input),
activeRuns: (companyId: string, connectionId: string) => api.get<Array<{ id: string; agentId: string; agentName: string; status: string }>>(`/companies/${companyId}/ai-connections/${connectionId}/active-runs`),
list: (companyId: string, agentId?: string) => api.get<{ currentUserId: string; connections: AiManagedConnectionSummary[] }>(`/companies/${companyId}/ai-connections${agentId ? `?agentId=${encodeURIComponent(agentId)}` : ""}`),
create: (companyId: string, input: CreateAiConnection) => api.post<{ connectionId: string; grantId: string }>(`/companies/${companyId}/ai-connections`, input),
setDefault: (companyId: string, grantId: string) => api.put(`/companies/${companyId}/ai-connections/default`, { grantId }),
loginResult: (companyId: string, sessionId: string) => api.get<{ connectionId: string; grantId: string }>(`/companies/${companyId}/ai-connections/login/${encodeURIComponent(sessionId)}`),
};
+8 -1
View File
@@ -1,5 +1,7 @@
import { api } from "./client";
import type {
PhotonProjectInspection,
PhotonChannelConfiguration,
ChatPublicationBatchStatus,
ChatPublicationState,
ChatPublicationSummary,
@@ -12,7 +14,7 @@ export type {
} from "@paperclipai/shared";
export type ChatProvider =
"slack" | "github" | "discord" | "microsoft-teams" | "telegram" | "agentmail";
"slack" | "github" | "discord" | "microsoft-teams" | "telegram" | "agentmail" | "imessage-photon";
export type ChatEndpointStatus =
| "draft"
| "verifying"
@@ -33,6 +35,7 @@ export interface ChatEndpointResource {
availability: "available" | "unavailable" | "removed";
enabled: boolean;
detail?: string | null;
participants?: string[];
}
export interface ChatIdentityLink {
@@ -97,6 +100,7 @@ export interface ChatEndpoint {
botLabel?: string | null;
botUsername?: string | null;
botExternalId?: string | null;
photonAllocation?: "dedicated" | "shared";
allowDirectMessages?: boolean;
allowGroupChats?: boolean;
allowUnlinkedPeople: boolean;
@@ -188,8 +192,11 @@ export const chatEndpointsApi = {
input: {
action: ChatEndpointSetupAction;
credentials?: Record<string, string>;
photon?: PhotonChannelConfiguration;
},
) => api.post<ChatEndpoint>(`/chat-endpoints/${endpointId}/setup`, input),
inspectPhoton: (endpointId: string, input: { projectId: string; projectSecret: string }) =>
api.post<PhotonProjectInspection>(`/chat-endpoints/${endpointId}/photon/inspect`, input),
generateSetupSecret: (endpointId: string) =>
api.post<ChatEndpointSetupSecret>(
`/chat-endpoints/${endpointId}/setup-secret`,
+1
View File
@@ -28,6 +28,7 @@ export type HealthStatus = {
version?: string;
deploymentMode?: "local_trusted" | "authenticated";
deploymentExposure?: "private" | "public";
localAiLoginSupported?: boolean;
authReady?: boolean;
bootstrapStatus?: "ready" | "bootstrap_pending";
bootstrapInviteActive?: boolean;
+17
View File
@@ -29,6 +29,23 @@ describe("issuesApi.list", () => {
mockApi.patch.mockResolvedValue({});
});
it.each([null, "stopped-run"])("dispatches a stopped queue using its current revision (%s)", async (target) => {
mockApi.get.mockResolvedValueOnce({ queueId: "queue-1", targetRunId: null, revision: "revision-2" });
await issuesApi.interruptLatestQueuedComments("issue-1", target);
expect(mockApi.post).toHaveBeenCalledWith("/issues/issue-1/queued-comments/interrupt", {
queueId: "queue-1", targetRunId: null, revision: "revision-2",
});
});
it.each([
{ queueId: null, targetRunId: null, revision: "empty" },
{ queueId: "queue-1", targetRunId: "new-run", revision: "changed" },
])("rejects a changed or empty queue before interruption", async queue => {
mockApi.get.mockResolvedValueOnce(queue);
await expect(issuesApi.interruptLatestQueuedComments("issue-1", "old-run")).rejects.toThrow("queued messages changed");
expect(mockApi.post).not.toHaveBeenCalled();
});
it("fetches all pages of tasks created from the source without filtering parentage", async () => {
const firstPage = Array.from({ length: 500 }, (_, index) => ({ id: `task-${index}` }));
mockApi.get.mockResolvedValueOnce(firstPage).mockResolvedValueOnce([{ id: "last-task" }]);
+10 -1
View File
@@ -386,8 +386,17 @@ export const issuesApi = {
),
interruptQueuedComments: (
id: string,
data: { queueId: string; targetRunId: string; revision: string },
data: { queueId: string; targetRunId: string | null; revision: string },
) => api.post<IssueQueuedCommentQueue>(`/issues/${id}/queued-comments/interrupt`, data),
interruptLatestQueuedComments: async (id: string, expectedTargetRunId: string | null): Promise<IssueQueuedCommentQueue> => {
const queue = await issuesApi.getQueuedComments(id);
if (!queue.queueId || (queue.targetRunId && queue.targetRunId !== expectedTargetRunId)) {
throw new Error("The queued messages changed. Refresh and try again.");
}
return issuesApi.interruptQueuedComments(id, {
queueId: queue.queueId, revision: queue.revision, targetRunId: queue.targetRunId,
});
},
steerQueuedComment: (
id: string,
commentId: string,