@polpo-ai/server 0.2.2

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.
Files changed (73) hide show
  1. package/dist/deps.d.ts +164 -0
  2. package/dist/deps.d.ts.map +1 -0
  3. package/dist/deps.js +9 -0
  4. package/dist/deps.js.map +1 -0
  5. package/dist/errors.d.ts +7 -0
  6. package/dist/errors.d.ts.map +1 -0
  7. package/dist/errors.js +12 -0
  8. package/dist/errors.js.map +1 -0
  9. package/dist/index.d.ts +25 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +25 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/playbook-utils.d.ts +36 -0
  14. package/dist/playbook-utils.d.ts.map +1 -0
  15. package/dist/playbook-utils.js +80 -0
  16. package/dist/playbook-utils.js.map +1 -0
  17. package/dist/routes/approvals.d.ts +17 -0
  18. package/dist/routes/approvals.d.ts.map +1 -0
  19. package/dist/routes/approvals.js +201 -0
  20. package/dist/routes/approvals.js.map +1 -0
  21. package/dist/routes/chat.d.ts +9 -0
  22. package/dist/routes/chat.d.ts.map +1 -0
  23. package/dist/routes/chat.js +170 -0
  24. package/dist/routes/chat.js.map +1 -0
  25. package/dist/routes/health.d.ts +7 -0
  26. package/dist/routes/health.d.ts.map +1 -0
  27. package/dist/routes/health.js +44 -0
  28. package/dist/routes/health.js.map +1 -0
  29. package/dist/routes/missions.d.ts +36 -0
  30. package/dist/routes/missions.d.ts.map +1 -0
  31. package/dist/routes/missions.js +636 -0
  32. package/dist/routes/missions.js.map +1 -0
  33. package/dist/routes/notifications.d.ts +8 -0
  34. package/dist/routes/notifications.d.ts.map +1 -0
  35. package/dist/routes/notifications.js +240 -0
  36. package/dist/routes/notifications.js.map +1 -0
  37. package/dist/routes/peers.d.ts +16 -0
  38. package/dist/routes/peers.d.ts.map +1 -0
  39. package/dist/routes/peers.js +183 -0
  40. package/dist/routes/peers.js.map +1 -0
  41. package/dist/routes/playbooks.d.ts +12 -0
  42. package/dist/routes/playbooks.d.ts.map +1 -0
  43. package/dist/routes/playbooks.js +223 -0
  44. package/dist/routes/playbooks.js.map +1 -0
  45. package/dist/routes/schedules.d.ts +7 -0
  46. package/dist/routes/schedules.d.ts.map +1 -0
  47. package/dist/routes/schedules.js +193 -0
  48. package/dist/routes/schedules.js.map +1 -0
  49. package/dist/routes/state.d.ts +16 -0
  50. package/dist/routes/state.d.ts.map +1 -0
  51. package/dist/routes/state.js +196 -0
  52. package/dist/routes/state.js.map +1 -0
  53. package/dist/routes/tasks.d.ts +17 -0
  54. package/dist/routes/tasks.d.ts.map +1 -0
  55. package/dist/routes/tasks.js +379 -0
  56. package/dist/routes/tasks.js.map +1 -0
  57. package/dist/routes/vault.d.ts +14 -0
  58. package/dist/routes/vault.d.ts.map +1 -0
  59. package/dist/routes/vault.js +237 -0
  60. package/dist/routes/vault.js.map +1 -0
  61. package/dist/routes/watchers.d.ts +6 -0
  62. package/dist/routes/watchers.d.ts.map +1 -0
  63. package/dist/routes/watchers.js +119 -0
  64. package/dist/routes/watchers.js.map +1 -0
  65. package/dist/schemas.d.ts +406 -0
  66. package/dist/schemas.d.ts.map +1 -0
  67. package/dist/schemas.js +314 -0
  68. package/dist/schemas.js.map +1 -0
  69. package/dist/security.d.ts +33 -0
  70. package/dist/security.d.ts.map +1 -0
  71. package/dist/security.js +66 -0
  72. package/dist/security.js.map +1 -0
  73. package/package.json +46 -0
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Vault REST API — direct CRUD for encrypted vault entries.
3
+ *
4
+ * POST /vault/entries — Save a vault entry (used by UI after vault_preview confirm)
5
+ * DELETE /vault/entries/:agent/:service — Remove a vault entry
6
+ *
7
+ * This bypasses the LLM entirely — credentials go straight to the encrypted store.
8
+ * No credentials are logged, persisted in session history, or returned in responses.
9
+ */
10
+ import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
11
+ export function vaultRoutes(getDeps) {
12
+ const app = new OpenAPIHono();
13
+ // POST /vault/entries — save a vault entry
14
+ const saveEntryRoute = createRoute({
15
+ method: "post",
16
+ path: "/entries",
17
+ tags: ["Vault"],
18
+ summary: "Save vault entry",
19
+ description: "Save credentials to the encrypted vault store. Credentials are encrypted at rest (AES-256-GCM) and never logged or persisted in chat history.",
20
+ request: {
21
+ body: {
22
+ content: {
23
+ "application/json": {
24
+ schema: z.object({
25
+ agent: z.string().min(1).describe("Agent name"),
26
+ service: z.string().min(1).describe("Service name (vault key)"),
27
+ type: z.enum(["smtp", "imap", "oauth", "api_key", "login", "custom"]).describe("Credential type"),
28
+ label: z.string().optional().describe("Human-readable label"),
29
+ credentials: z.record(z.string(), z.string()).describe("Key-value credential fields"),
30
+ }),
31
+ },
32
+ },
33
+ },
34
+ },
35
+ responses: {
36
+ 200: {
37
+ content: {
38
+ "application/json": {
39
+ schema: z.object({
40
+ ok: z.boolean(),
41
+ data: z.object({
42
+ agent: z.string(),
43
+ service: z.string(),
44
+ type: z.string(),
45
+ keys: z.array(z.string()),
46
+ }),
47
+ }),
48
+ },
49
+ },
50
+ description: "Vault entry saved successfully",
51
+ },
52
+ 503: {
53
+ content: { "application/json": { schema: z.object({ ok: z.boolean(), error: z.string() }) } },
54
+ description: "Vault store not available",
55
+ },
56
+ },
57
+ });
58
+ app.openapi(saveEntryRoute, async (c) => {
59
+ const { vaultStore } = getDeps();
60
+ if (!vaultStore) {
61
+ return c.json({ ok: false, error: "Vault store not available. Check POLPO_VAULT_KEY or ~/.polpo/vault.key." }, 503);
62
+ }
63
+ const body = c.req.valid("json");
64
+ const entry = {
65
+ type: body.type,
66
+ ...(body.label ? { label: body.label } : {}),
67
+ credentials: body.credentials,
68
+ };
69
+ await vaultStore.set(body.agent, body.service, entry);
70
+ // Return only metadata — NEVER return credential values
71
+ return c.json({
72
+ ok: true,
73
+ data: {
74
+ agent: body.agent,
75
+ service: body.service,
76
+ type: body.type,
77
+ keys: Object.keys(body.credentials),
78
+ },
79
+ }, 200);
80
+ });
81
+ // GET /vault/entries/:agent — list vault entries (metadata only, no credential values)
82
+ const listEntriesRoute = createRoute({
83
+ method: "get",
84
+ path: "/entries/{agent}",
85
+ tags: ["Vault"],
86
+ summary: "List vault entries",
87
+ description: "Returns metadata (service name, type, label, credential key names) without any secret values.",
88
+ request: {
89
+ params: z.object({
90
+ agent: z.string(),
91
+ }),
92
+ },
93
+ responses: {
94
+ 200: {
95
+ content: {
96
+ "application/json": {
97
+ schema: z.object({
98
+ ok: z.boolean(),
99
+ data: z.array(z.object({
100
+ service: z.string(),
101
+ type: z.enum(["smtp", "imap", "oauth", "api_key", "login", "custom"]),
102
+ label: z.string().optional(),
103
+ keys: z.array(z.string()),
104
+ })),
105
+ }),
106
+ },
107
+ },
108
+ description: "Vault entries metadata for the agent",
109
+ },
110
+ 503: {
111
+ content: { "application/json": { schema: z.object({ ok: z.boolean(), error: z.string() }) } },
112
+ description: "Vault store not available",
113
+ },
114
+ },
115
+ });
116
+ app.openapi(listEntriesRoute, async (c) => {
117
+ const { vaultStore } = getDeps();
118
+ if (!vaultStore) {
119
+ return c.json({ ok: false, error: "Vault store not available. Check POLPO_VAULT_KEY or ~/.polpo/vault.key." }, 503);
120
+ }
121
+ const { agent } = c.req.valid("param");
122
+ const entries = await vaultStore.list(agent);
123
+ return c.json({ ok: true, data: entries }, 200);
124
+ });
125
+ // PATCH /vault/entries/:agent/:service — partially update credentials
126
+ const patchEntryRoute = createRoute({
127
+ method: "patch",
128
+ path: "/entries/{agent}/{service}",
129
+ tags: ["Vault"],
130
+ summary: "Update vault credentials",
131
+ description: "Partially update credential fields in an existing vault entry. Only the provided fields are merged — existing fields are preserved. Optionally update type and label.",
132
+ request: {
133
+ params: z.object({
134
+ agent: z.string(),
135
+ service: z.string(),
136
+ }),
137
+ body: {
138
+ content: {
139
+ "application/json": {
140
+ schema: z.object({
141
+ type: z.enum(["smtp", "imap", "oauth", "api_key", "login", "custom"]).optional().describe("Update credential type"),
142
+ label: z.string().optional().describe("Update human-readable label"),
143
+ credentials: z.record(z.string(), z.string()).optional().describe("Credential fields to add or update (merged with existing)"),
144
+ }),
145
+ },
146
+ },
147
+ },
148
+ },
149
+ responses: {
150
+ 200: {
151
+ content: {
152
+ "application/json": {
153
+ schema: z.object({
154
+ ok: z.boolean(),
155
+ data: z.object({
156
+ agent: z.string(),
157
+ service: z.string(),
158
+ type: z.string(),
159
+ keys: z.array(z.string()),
160
+ }),
161
+ }),
162
+ },
163
+ },
164
+ description: "Vault entry updated successfully",
165
+ },
166
+ 404: {
167
+ content: { "application/json": { schema: z.object({ ok: z.boolean(), error: z.string() }) } },
168
+ description: "Vault entry not found",
169
+ },
170
+ 503: {
171
+ content: { "application/json": { schema: z.object({ ok: z.boolean(), error: z.string() }) } },
172
+ description: "Vault store not available",
173
+ },
174
+ },
175
+ });
176
+ app.openapi(patchEntryRoute, async (c) => {
177
+ const { vaultStore } = getDeps();
178
+ if (!vaultStore) {
179
+ return c.json({ ok: false, error: "Vault store not available. Check POLPO_VAULT_KEY or ~/.polpo/vault.key." }, 503);
180
+ }
181
+ const { agent, service } = c.req.valid("param");
182
+ const existing = await vaultStore.get(agent, service);
183
+ if (!existing) {
184
+ return c.json({ ok: false, error: `No vault entry "${service}" for agent "${agent}".` }, 404);
185
+ }
186
+ const body = c.req.valid("json");
187
+ const mergedKeys = await vaultStore.patch(agent, service, {
188
+ type: body.type,
189
+ label: body.label,
190
+ credentials: body.credentials,
191
+ });
192
+ const updated = (await vaultStore.get(agent, service));
193
+ return c.json({
194
+ ok: true,
195
+ data: {
196
+ agent,
197
+ service,
198
+ type: updated.type,
199
+ keys: mergedKeys,
200
+ },
201
+ }, 200);
202
+ });
203
+ // DELETE /vault/entries/:agent/:service — remove a vault entry
204
+ const deleteEntryRoute = createRoute({
205
+ method: "delete",
206
+ path: "/entries/{agent}/{service}",
207
+ tags: ["Vault"],
208
+ summary: "Remove vault entry",
209
+ request: {
210
+ params: z.object({
211
+ agent: z.string(),
212
+ service: z.string(),
213
+ }),
214
+ },
215
+ responses: {
216
+ 200: {
217
+ content: { "application/json": { schema: z.object({ ok: z.boolean(), data: z.object({ removed: z.boolean() }) }) } },
218
+ description: "Result",
219
+ },
220
+ 503: {
221
+ content: { "application/json": { schema: z.object({ ok: z.boolean(), error: z.string() }) } },
222
+ description: "Vault store not available",
223
+ },
224
+ },
225
+ });
226
+ app.openapi(deleteEntryRoute, async (c) => {
227
+ const { vaultStore } = getDeps();
228
+ if (!vaultStore) {
229
+ return c.json({ ok: false, error: "Vault store not available." }, 503);
230
+ }
231
+ const { agent, service } = c.req.valid("param");
232
+ const removed = await vaultStore.remove(agent, service);
233
+ return c.json({ ok: true, data: { removed } }, 200);
234
+ });
235
+ return app;
236
+ }
237
+ //# sourceMappingURL=vault.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault.js","sourceRoot":"","sources":["../../src/routes/vault.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { OpenAPIHono } from "@hono/zod-openapi";
2
+ export declare function watcherRoutes(getDeps: () => {
3
+ getWatcherManager: () => any;
4
+ taskStore: any;
5
+ }): OpenAPIHono;
6
+ //# sourceMappingURL=watchers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watchers.d.ts","sourceRoot":"","sources":["../../src/routes/watchers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AA4EhE,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM;IAC3C,iBAAiB,EAAE,MAAM,GAAG,CAAC;IAC7B,SAAS,EAAE,GAAG,CAAC;CAChB,GAAG,WAAW,CAuDd"}
@@ -0,0 +1,119 @@
1
+ import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
2
+ // ── Route definitions ─────────────────────────────────────────────────
3
+ const listWatchersRoute = createRoute({
4
+ method: "get",
5
+ path: "/",
6
+ tags: ["Watchers"],
7
+ summary: "List watchers",
8
+ request: {
9
+ query: z.object({
10
+ active: z.string().optional(),
11
+ }),
12
+ },
13
+ responses: {
14
+ 200: {
15
+ content: { "application/json": { schema: z.object({ ok: z.boolean(), data: z.array(z.any()) }) } },
16
+ description: "List of watchers",
17
+ },
18
+ },
19
+ });
20
+ const createWatcherRoute = createRoute({
21
+ method: "post",
22
+ path: "/",
23
+ tags: ["Watchers"],
24
+ summary: "Create watcher",
25
+ request: {
26
+ body: {
27
+ content: {
28
+ "application/json": {
29
+ schema: z.object({
30
+ taskId: z.string().min(1),
31
+ targetStatus: z.enum(["pending", "assigned", "in_progress", "review", "done", "failed", "awaiting_approval"]),
32
+ action: z.object({
33
+ type: z.string().min(1),
34
+ }).passthrough(),
35
+ }),
36
+ },
37
+ },
38
+ },
39
+ },
40
+ responses: {
41
+ 201: {
42
+ content: { "application/json": { schema: z.object({ ok: z.boolean(), data: z.any() }) } },
43
+ description: "Watcher created",
44
+ },
45
+ 400: {
46
+ content: { "application/json": { schema: z.object({ ok: z.boolean(), error: z.string(), code: z.string() }) } },
47
+ description: "Watcher manager unavailable or task not found",
48
+ },
49
+ },
50
+ });
51
+ const deleteWatcherRoute = createRoute({
52
+ method: "delete",
53
+ path: "/{watcherId}",
54
+ tags: ["Watchers"],
55
+ summary: "Delete watcher",
56
+ request: {
57
+ params: z.object({ watcherId: z.string() }),
58
+ },
59
+ responses: {
60
+ 200: {
61
+ content: { "application/json": { schema: z.object({ ok: z.boolean(), data: z.object({ deleted: z.boolean() }) }) } },
62
+ description: "Watcher deleted",
63
+ },
64
+ 404: {
65
+ content: { "application/json": { schema: z.object({ ok: z.boolean(), error: z.string(), code: z.string() }) } },
66
+ description: "Watcher not found",
67
+ },
68
+ },
69
+ });
70
+ // ── Route handlers ────────────────────────────────────────────────────
71
+ export function watcherRoutes(getDeps) {
72
+ const app = new OpenAPIHono();
73
+ // GET /watchers — list watchers
74
+ app.openapi(listWatchersRoute, (c) => {
75
+ const deps = getDeps();
76
+ const watcherMgr = deps.getWatcherManager();
77
+ if (!watcherMgr) {
78
+ return c.json({ ok: true, data: [] });
79
+ }
80
+ const query = c.req.valid("query");
81
+ const watchers = query.active === "true" ? watcherMgr.getActive() : watcherMgr.getAll();
82
+ return c.json({ ok: true, data: watchers });
83
+ });
84
+ // POST /watchers — create a watcher
85
+ app.openapi(createWatcherRoute, async (c) => {
86
+ const deps = getDeps();
87
+ const watcherMgr = deps.getWatcherManager();
88
+ if (!watcherMgr) {
89
+ return c.json({ ok: false, error: "Watcher manager not available", code: "NOT_AVAILABLE" }, 400);
90
+ }
91
+ const body = c.req.valid("json");
92
+ const task = await deps.taskStore.getTask(body.taskId);
93
+ if (!task) {
94
+ return c.json({ ok: false, error: `Task "${body.taskId}" not found`, code: "NOT_FOUND" }, 400);
95
+ }
96
+ const watcher = watcherMgr.create({
97
+ taskId: body.taskId,
98
+ targetStatus: body.targetStatus,
99
+ action: body.action,
100
+ });
101
+ return c.json({ ok: true, data: watcher }, 201);
102
+ });
103
+ // DELETE /watchers/:watcherId — delete a watcher
104
+ app.openapi(deleteWatcherRoute, (c) => {
105
+ const deps = getDeps();
106
+ const watcherMgr = deps.getWatcherManager();
107
+ if (!watcherMgr) {
108
+ return c.json({ ok: false, error: "Watcher manager not available", code: "NOT_FOUND" }, 404);
109
+ }
110
+ const { watcherId } = c.req.valid("param");
111
+ const removed = watcherMgr.remove(watcherId);
112
+ if (!removed) {
113
+ return c.json({ ok: false, error: `Watcher "${watcherId}" not found`, code: "NOT_FOUND" }, 404);
114
+ }
115
+ return c.json({ ok: true, data: { deleted: true } }, 200);
116
+ });
117
+ return app;
118
+ }
119
+ //# sourceMappingURL=watchers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watchers.js","sourceRoot":"","sources":["../../src/routes/watchers.ts"],"names":[],"mappings":"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"}