@pstdio/sdk 0.2.0 → 0.2.1

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.
@@ -6,6 +6,7 @@ export type ExecuteActionInput = {
6
6
  export type ActionResult = {
7
7
  status: "success";
8
8
  session_id?: string;
9
+ message?: string;
9
10
  } | {
10
11
  status: "error";
11
12
  message: string;
@@ -24,6 +24,8 @@ var createProjectClient = (request) => ({
24
24
  get: (projectId) => request(`/v1/projects/${projectId}`),
25
25
  create: (input) => request("/v1/projects", { method: "POST", body: input }),
26
26
  delete: (projectId) => request(`/v1/projects/${projectId}`, { method: "DELETE" }),
27
+ listPlugins: (projectId) => request(`/v1/projects/${projectId}/plugins`),
28
+ registerPlugins: (projectId) => request(`/v1/projects/${projectId}/plugins/register`, { method: "POST" }),
27
29
  listRepos: (projectId) => request(`/v1/projects/${projectId}/repos`),
28
30
  registerRepo: (projectId, input) => request(`/v1/projects/${projectId}/repos`, { method: "POST", body: input }),
29
31
  removeRepo: (projectId, repoId) => request(`/v1/projects/${projectId}/repos/${repoId}`, { method: "DELETE" })
@@ -38,9 +40,29 @@ class PstdioApiError extends Error {
38
40
  this.status = status;
39
41
  }
40
42
  }
43
+ var formatZodIssues = (issues) => issues.map((issue) => {
44
+ const path = Array.isArray(issue.path) ? issue.path.filter((part) => part !== "").join(".") : "";
45
+ const message = typeof issue.message === "string" ? issue.message : JSON.stringify(issue);
46
+ return path ? `${path}: ${message}` : message;
47
+ }).join("; ");
48
+ var stringifyErrorField = (error) => {
49
+ if (typeof error === "string")
50
+ return error;
51
+ if (error && typeof error === "object") {
52
+ const issues = error.issues;
53
+ if (Array.isArray(issues))
54
+ return formatZodIssues(issues);
55
+ try {
56
+ return JSON.stringify(error);
57
+ } catch {
58
+ return String(error);
59
+ }
60
+ }
61
+ return String(error);
62
+ };
41
63
  var readErrorMessage = (errorBody, status) => {
42
64
  if (errorBody && typeof errorBody === "object" && errorBody !== null && "error" in errorBody) {
43
- const message = String(errorBody.error);
65
+ const message = stringifyErrorField(errorBody.error);
44
66
  const hookOutput = "hook_output" in errorBody && typeof errorBody.hook_output === "string" ? errorBody.hook_output.trim() : "";
45
67
  return hookOutput ? `${message}
46
68
  ${hookOutput}` : message;
@@ -1,13 +1,24 @@
1
1
  import type { CreateProjectInput, RegisterRepoInput, Repo } from "pstdio-api-contracts";
2
2
  import type { Project } from "../resources";
3
3
  import type { RequestFn } from "./request";
4
+ type RegisteredPlugin = {
5
+ identity: string;
6
+ filePath: string;
7
+ };
8
+ type RegisteredPluginsResponse = {
9
+ plugins: RegisteredPlugin[];
10
+ pluginsDir: string | null;
11
+ };
4
12
  export type ProjectClient = {
5
13
  list(): Promise<Project[]>;
6
14
  get(projectId: string): Promise<Project>;
7
15
  create(input: CreateProjectInput): Promise<Project>;
8
16
  delete(projectId: string): Promise<void>;
17
+ listPlugins(projectId: string): Promise<RegisteredPluginsResponse>;
18
+ registerPlugins(projectId: string): Promise<RegisteredPluginsResponse>;
9
19
  listRepos(projectId: string): Promise<Repo[]>;
10
20
  registerRepo(projectId: string, input: RegisterRepoInput): Promise<Repo>;
11
21
  removeRepo(projectId: string, repoId: string): Promise<void>;
12
22
  };
13
23
  export declare const createProjectClient: (request: RequestFn) => ProjectClient;
24
+ export {};
@@ -2,7 +2,7 @@ import type { BaseHookContext } from "./base";
2
2
  import type { HookTicket, HookWorkspace } from "./entities";
3
3
  export type SessionHookContext = BaseHookContext & {
4
4
  sessionId: string;
5
- sessionStatus: "in_progress" | "awaiting_input" | "completed" | "failed" | "cancelled";
5
+ sessionStatus: "in_progress" | "awaiting_input" | "completed" | "failed" | "cancelled" | "disconnected";
6
6
  originalSessionId?: string;
7
7
  workspace?: HookWorkspace;
8
8
  workspaceId?: string;
@@ -5,7 +5,7 @@ export declare const createSession: (ctx: PluginHelperContext, input: CreateSess
5
5
  id: string;
6
6
  project_id: string | null;
7
7
  title: string;
8
- status: "in_progress" | "awaiting_input" | "completed" | "failed" | "cancelled";
8
+ status: "in_progress" | "awaiting_input" | "completed" | "failed" | "cancelled" | "disconnected";
9
9
  archived: boolean;
10
10
  last_request_started: string | null;
11
11
  last_request_ended: string | null;
@@ -7,7 +7,7 @@ export declare const followupSession: (ctx: PluginHelperContext, input: Followup
7
7
  id: string;
8
8
  project_id: string | null;
9
9
  title: string;
10
- status: "in_progress" | "awaiting_input" | "completed" | "failed" | "cancelled";
10
+ status: "in_progress" | "awaiting_input" | "completed" | "failed" | "cancelled" | "disconnected";
11
11
  archived: boolean;
12
12
  last_request_started: string | null;
13
13
  last_request_ended: string | null;
@@ -1,4 +1,5 @@
1
1
  type CommandOutputOptions = {
2
+ env?: NodeJS.ProcessEnv;
2
3
  quiet?: boolean;
3
4
  };
4
5
  export declare const runCommand: (cwd: string, command: string[], options?: CommandOutputOptions) => Promise<{
@@ -2,4 +2,4 @@ export { renderPrompt } from "../prompts";
2
2
  export { definePlugin } from "./define-plugin";
3
3
  export { bootstrapWorktree, createAttempt, createSession, createWorkspace, findTicketByRef, findWorkspaceByRef, followupSession, getAttemptsForTicket, type PullTicketsInput, type PullTicketsResult, pullTickets, removeAllWorktreesForTicket, runCommand, setTicketStatus, setWorkspaceAttemptStatus, updateTicketWhenAllAttemptsMatch, workspacesForTicket, } from "./helpers";
4
4
  export type { HookResponse, PluginHooks, PostHookReturn, PostPluginHooks, PreHookReturn, PrePluginHooks, } from "./hooks";
5
- export type { ActionDefinition, ActionDescriptor, ActionInput, ActionParamDef, ActionParamValue, ActionPlacement, ActionTargetMap, ActionTriggerContext, AgentActionParam, AgentParamValue, LongTextActionParam, PluginDefinition, RepoActionParam, RepoParamValue, SelectActionParam, TargetType, TemplateSelectActionParam, TextActionParam, } from "./types";
5
+ export type { ActionDefinition, ActionDescriptor, ActionInput, ActionParamDef, ActionParamValue, ActionPlacement, ActionTargetMap, ActionTriggerContext, ActionTriggerResult, AgentActionParam, AgentParamValue, LongTextActionParam, PluginDefinition, RepoActionParam, RepoParamValue, SelectActionParam, TargetType, TemplateSelectActionParam, TextActionParam, } from "./types";
@@ -170,24 +170,29 @@ var removeAllWorktreesForTicket = async (ctx, input) => {
170
170
  return removed;
171
171
  };
172
172
  // src/plugins/helpers/run-command.ts
173
- import { spawn as nodeSpawn } from "node:child_process";
174
173
  var runCommand = async (cwd, command, options = {}) => {
175
174
  const [cmd, ...args] = command;
176
175
  const stdio = options.quiet ? "ignore" : "pipe";
177
- return new Promise((resolve) => {
178
- const proc = nodeSpawn(cmd, args, { cwd, stdio: ["ignore", stdio, stdio] });
179
- const stdout = [];
180
- const stderr = [];
181
- proc.stdout?.on("data", (chunk) => stdout.push(chunk.toString()));
182
- proc.stderr?.on("data", (chunk) => stderr.push(chunk.toString()));
183
- proc.on("close", (code) => {
184
- resolve({
185
- exitCode: code ?? 1,
186
- stdout: stdout.join("").trim(),
187
- stderr: stderr.join("").trim()
188
- });
176
+ let proc;
177
+ try {
178
+ proc = Bun.spawn([cmd, ...args], {
179
+ cwd,
180
+ env: options.env,
181
+ stdin: "ignore",
182
+ stdout: stdio,
183
+ stderr: stdio
189
184
  });
190
- });
185
+ } catch (error) {
186
+ return { exitCode: 1, stdout: "", stderr: error.message };
187
+ }
188
+ const readStream = (stream) => stream && typeof stream !== "number" ? new Response(stream).text() : Promise.resolve("");
189
+ const [stdout, stderr] = await Promise.all([readStream(proc.stdout), readStream(proc.stderr)]);
190
+ const exitCode = await proc.exited;
191
+ return {
192
+ exitCode,
193
+ stdout: stdout.trim(),
194
+ stderr: stderr.trim()
195
+ };
191
196
  };
192
197
  // src/plugins/helpers/set-ticket-status.ts
193
198
  var setTicketStatus = async (ctx, input) => {
@@ -61,6 +61,11 @@ export type ActionTriggerContext<TTargetType extends TargetType = TargetType> =
61
61
  targetId: string;
62
62
  target: ActionTargetMap[TTargetType];
63
63
  } : never);
64
+ export type ActionTriggerResult = {
65
+ session_id?: string;
66
+ message?: string;
67
+ };
68
+ type ActionTrigger<TTargetType extends TargetType = TargetType> = ((ctx: ActionTriggerContext<TTargetType>) => void) | ((ctx: ActionTriggerContext<TTargetType>) => ActionTriggerResult) | ((ctx: ActionTriggerContext<TTargetType>) => Promise<ActionTriggerResult | undefined>);
64
69
  export type ActionInput = {
65
70
  [K in TargetType]: {
66
71
  key: string;
@@ -68,7 +73,7 @@ export type ActionInput = {
68
73
  targetType: K;
69
74
  placement: ActionPlacement;
70
75
  params?: ActionParamDef[];
71
- trigger: (ctx: ActionTriggerContext<K>) => void | Promise<void>;
76
+ trigger: ActionTrigger<K>;
72
77
  };
73
78
  }[TargetType];
74
79
  export type ActionDescriptor = {
@@ -79,7 +84,7 @@ export type ActionDescriptor = {
79
84
  params?: ActionParamDef[];
80
85
  };
81
86
  export type ActionDefinition = ActionDescriptor & {
82
- trigger: (ctx: ActionTriggerContext) => void | Promise<void>;
87
+ trigger: ActionTrigger;
83
88
  };
84
89
  export type PluginDefinition = {
85
90
  key?: string;
@@ -3,7 +3,7 @@ export type { AgentAvailabilityType, AgentConfig, AgentInfo, AgentModel } from "
3
3
  export type { FileRecord } from "./file";
4
4
  export type { Project } from "./project";
5
5
  export type { Session, SessionStatus } from "./session";
6
- export type { Skill, SkillWithContent } from "./skill";
6
+ export type { Skill, SkillFile, SkillWithContent } from "./skill";
7
7
  export type { AttemptStatus, Status } from "./status";
8
8
  export type { Tag, TagOption } from "./tag";
9
9
  export type { Template, TemplateType, TemplateWithContent } from "./template";
@@ -1 +1 @@
1
- export type { Skill, SkillWithContent } from "pstdio-api-contracts";
1
+ export type { Skill, SkillFile, SkillWithContent } from "pstdio-api-contracts";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pstdio/sdk",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/pufflyai/prompt-studio"
@@ -56,6 +56,6 @@
56
56
  "@types/bun": "latest",
57
57
  "@types/mustache": "^4.2.6",
58
58
  "pstdio-api-contracts": "workspace:*",
59
- "typescript": "^5.9.3"
59
+ "typescript": "6.0.2"
60
60
  }
61
61
  }