patchwork-os 0.2.0-alpha.3 → 0.2.0-alpha.31

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 (301) hide show
  1. package/README.bridge.md +6 -0
  2. package/README.md +40 -15
  3. package/deploy/bootstrap-vps.sh +184 -0
  4. package/deploy/deploy-dashboard.sh +174 -0
  5. package/deploy/deploy-landing.sh +79 -0
  6. package/dist/activationMetrics.d.ts +67 -0
  7. package/dist/activationMetrics.js +255 -0
  8. package/dist/activationMetrics.js.map +1 -0
  9. package/dist/approvalHttp.d.ts +24 -2
  10. package/dist/approvalHttp.js +150 -10
  11. package/dist/approvalHttp.js.map +1 -1
  12. package/dist/approvalQueue.d.ts +16 -1
  13. package/dist/approvalQueue.js +44 -3
  14. package/dist/approvalQueue.js.map +1 -1
  15. package/dist/automation.d.ts +20 -0
  16. package/dist/automation.js +54 -1
  17. package/dist/automation.js.map +1 -1
  18. package/dist/bridge.d.ts +2 -0
  19. package/dist/bridge.js +55 -130
  20. package/dist/bridge.js.map +1 -1
  21. package/dist/bridgeToken.js +57 -19
  22. package/dist/bridgeToken.js.map +1 -1
  23. package/dist/ccPermissions.js +6 -4
  24. package/dist/ccPermissions.js.map +1 -1
  25. package/dist/claudeOrchestrator.d.ts +1 -1
  26. package/dist/claudeOrchestrator.js +14 -8
  27. package/dist/claudeOrchestrator.js.map +1 -1
  28. package/dist/commands/launchd.d.ts +2 -0
  29. package/dist/commands/launchd.js +94 -0
  30. package/dist/commands/launchd.js.map +1 -0
  31. package/dist/commands/recipe.d.ts +258 -0
  32. package/dist/commands/recipe.js +1130 -0
  33. package/dist/commands/recipe.js.map +1 -0
  34. package/dist/commands/recipeInstall.d.ts +72 -0
  35. package/dist/commands/recipeInstall.js +339 -0
  36. package/dist/commands/recipeInstall.js.map +1 -0
  37. package/dist/config.d.ts +14 -1
  38. package/dist/config.js +99 -8
  39. package/dist/config.js.map +1 -1
  40. package/dist/connectors/baseConnector.d.ts +117 -0
  41. package/dist/connectors/baseConnector.js +213 -0
  42. package/dist/connectors/baseConnector.js.map +1 -0
  43. package/dist/connectors/confluence.d.ts +111 -0
  44. package/dist/connectors/confluence.js +406 -0
  45. package/dist/connectors/confluence.js.map +1 -0
  46. package/dist/connectors/datadog.d.ts +116 -0
  47. package/dist/connectors/datadog.js +385 -0
  48. package/dist/connectors/datadog.js.map +1 -0
  49. package/dist/connectors/fixtureLibrary.d.ts +21 -0
  50. package/dist/connectors/fixtureLibrary.js +70 -0
  51. package/dist/connectors/fixtureLibrary.js.map +1 -0
  52. package/dist/connectors/fixtureRecorder.d.ts +1 -0
  53. package/dist/connectors/fixtureRecorder.js +35 -0
  54. package/dist/connectors/fixtureRecorder.js.map +1 -0
  55. package/dist/connectors/github.d.ts +58 -8
  56. package/dist/connectors/github.js +312 -84
  57. package/dist/connectors/github.js.map +1 -1
  58. package/dist/connectors/gmail.d.ts +4 -1
  59. package/dist/connectors/gmail.js +79 -16
  60. package/dist/connectors/gmail.js.map +1 -1
  61. package/dist/connectors/googleCalendar.d.ts +60 -0
  62. package/dist/connectors/googleCalendar.js +345 -0
  63. package/dist/connectors/googleCalendar.js.map +1 -0
  64. package/dist/connectors/hubspot.d.ts +112 -0
  65. package/dist/connectors/hubspot.js +408 -0
  66. package/dist/connectors/hubspot.js.map +1 -0
  67. package/dist/connectors/intercom.d.ts +102 -0
  68. package/dist/connectors/intercom.js +402 -0
  69. package/dist/connectors/intercom.js.map +1 -0
  70. package/dist/connectors/jira.d.ts +98 -0
  71. package/dist/connectors/jira.js +379 -0
  72. package/dist/connectors/jira.js.map +1 -0
  73. package/dist/connectors/linear.d.ts +69 -19
  74. package/dist/connectors/linear.js +170 -129
  75. package/dist/connectors/linear.js.map +1 -1
  76. package/dist/connectors/mcpClient.d.ts +56 -0
  77. package/dist/connectors/mcpClient.js +189 -0
  78. package/dist/connectors/mcpClient.js.map +1 -0
  79. package/dist/connectors/mcpOAuth.d.ts +84 -0
  80. package/dist/connectors/mcpOAuth.js +389 -0
  81. package/dist/connectors/mcpOAuth.js.map +1 -0
  82. package/dist/connectors/mockConnector.d.ts +28 -0
  83. package/dist/connectors/mockConnector.js +81 -0
  84. package/dist/connectors/mockConnector.js.map +1 -0
  85. package/dist/connectors/notion.d.ts +143 -0
  86. package/dist/connectors/notion.js +424 -0
  87. package/dist/connectors/notion.js.map +1 -0
  88. package/dist/connectors/sentry.d.ts +17 -21
  89. package/dist/connectors/sentry.js +115 -131
  90. package/dist/connectors/sentry.js.map +1 -1
  91. package/dist/connectors/slack.d.ts +50 -0
  92. package/dist/connectors/slack.js +324 -0
  93. package/dist/connectors/slack.js.map +1 -0
  94. package/dist/connectors/stripe.d.ts +116 -0
  95. package/dist/connectors/stripe.js +379 -0
  96. package/dist/connectors/stripe.js.map +1 -0
  97. package/dist/connectors/tokenStorage.d.ts +35 -0
  98. package/dist/connectors/tokenStorage.js +459 -0
  99. package/dist/connectors/tokenStorage.js.map +1 -0
  100. package/dist/connectors/zendesk.d.ts +104 -0
  101. package/dist/connectors/zendesk.js +424 -0
  102. package/dist/connectors/zendesk.js.map +1 -0
  103. package/dist/drivers/gemini/index.d.ts +5 -1
  104. package/dist/drivers/gemini/index.js +39 -5
  105. package/dist/drivers/gemini/index.js.map +1 -1
  106. package/dist/drivers/index.d.ts +5 -0
  107. package/dist/drivers/index.js +1 -1
  108. package/dist/drivers/index.js.map +1 -1
  109. package/dist/featureFlags.d.ts +73 -0
  110. package/dist/featureFlags.js +203 -0
  111. package/dist/featureFlags.js.map +1 -0
  112. package/dist/fp/automationInterpreter.js +1 -0
  113. package/dist/fp/automationInterpreter.js.map +1 -1
  114. package/dist/fp/automationProgram.d.ts +1 -1
  115. package/dist/fp/automationProgram.js.map +1 -1
  116. package/dist/fp/policyParser.js +17 -0
  117. package/dist/fp/policyParser.js.map +1 -1
  118. package/dist/index.js +621 -61
  119. package/dist/index.js.map +1 -1
  120. package/dist/installGuard.d.ts +25 -0
  121. package/dist/installGuard.js +48 -0
  122. package/dist/installGuard.js.map +1 -0
  123. package/dist/oauth.d.ts +4 -1
  124. package/dist/oauth.js +50 -14
  125. package/dist/oauth.js.map +1 -1
  126. package/dist/patchworkConfig.d.ts +9 -0
  127. package/dist/patchworkConfig.js.map +1 -1
  128. package/dist/recipeOrchestration.d.ts +53 -0
  129. package/dist/recipeOrchestration.js +272 -0
  130. package/dist/recipeOrchestration.js.map +1 -0
  131. package/dist/recipes/RecipeOrchestrator.d.ts +40 -0
  132. package/dist/recipes/RecipeOrchestrator.js +51 -0
  133. package/dist/recipes/RecipeOrchestrator.js.map +1 -0
  134. package/dist/recipes/agentExecutor.d.ts +28 -0
  135. package/dist/recipes/agentExecutor.js +42 -0
  136. package/dist/recipes/agentExecutor.js.map +1 -0
  137. package/dist/recipes/chainedRunner.d.ts +140 -0
  138. package/dist/recipes/chainedRunner.js +539 -0
  139. package/dist/recipes/chainedRunner.js.map +1 -0
  140. package/dist/recipes/dependencyGraph.d.ts +39 -0
  141. package/dist/recipes/dependencyGraph.js +199 -0
  142. package/dist/recipes/dependencyGraph.js.map +1 -0
  143. package/dist/recipes/legacyRecipeCompat.d.ts +2 -0
  144. package/dist/recipes/legacyRecipeCompat.js +112 -0
  145. package/dist/recipes/legacyRecipeCompat.js.map +1 -0
  146. package/dist/recipes/manifest.d.ts +47 -0
  147. package/dist/recipes/manifest.js +141 -0
  148. package/dist/recipes/manifest.js.map +1 -0
  149. package/dist/recipes/nestedRecipeStep.d.ts +58 -0
  150. package/dist/recipes/nestedRecipeStep.js +95 -0
  151. package/dist/recipes/nestedRecipeStep.js.map +1 -0
  152. package/dist/recipes/outputRegistry.d.ts +28 -0
  153. package/dist/recipes/outputRegistry.js +52 -0
  154. package/dist/recipes/outputRegistry.js.map +1 -0
  155. package/dist/recipes/scheduler.d.ts +23 -7
  156. package/dist/recipes/scheduler.js +131 -41
  157. package/dist/recipes/scheduler.js.map +1 -1
  158. package/dist/recipes/schema.d.ts +17 -2
  159. package/dist/recipes/schemaGenerator.d.ts +28 -0
  160. package/dist/recipes/schemaGenerator.js +565 -0
  161. package/dist/recipes/schemaGenerator.js.map +1 -0
  162. package/dist/recipes/templateEngine.d.ts +62 -0
  163. package/dist/recipes/templateEngine.js +182 -0
  164. package/dist/recipes/templateEngine.js.map +1 -0
  165. package/dist/recipes/toolRegistry.d.ts +181 -0
  166. package/dist/recipes/toolRegistry.js +300 -0
  167. package/dist/recipes/toolRegistry.js.map +1 -0
  168. package/dist/recipes/tools/calendar.d.ts +6 -0
  169. package/dist/recipes/tools/calendar.js +61 -0
  170. package/dist/recipes/tools/calendar.js.map +1 -0
  171. package/dist/recipes/tools/confluence.d.ts +6 -0
  172. package/dist/recipes/tools/confluence.js +254 -0
  173. package/dist/recipes/tools/confluence.js.map +1 -0
  174. package/dist/recipes/tools/datadog.d.ts +6 -0
  175. package/dist/recipes/tools/datadog.js +239 -0
  176. package/dist/recipes/tools/datadog.js.map +1 -0
  177. package/dist/recipes/tools/diagnostics.d.ts +6 -0
  178. package/dist/recipes/tools/diagnostics.js +36 -0
  179. package/dist/recipes/tools/diagnostics.js.map +1 -0
  180. package/dist/recipes/tools/file.d.ts +6 -0
  181. package/dist/recipes/tools/file.js +170 -0
  182. package/dist/recipes/tools/file.js.map +1 -0
  183. package/dist/recipes/tools/git.d.ts +6 -0
  184. package/dist/recipes/tools/git.js +63 -0
  185. package/dist/recipes/tools/git.js.map +1 -0
  186. package/dist/recipes/tools/github.d.ts +6 -0
  187. package/dist/recipes/tools/github.js +91 -0
  188. package/dist/recipes/tools/github.js.map +1 -0
  189. package/dist/recipes/tools/gmail.d.ts +6 -0
  190. package/dist/recipes/tools/gmail.js +210 -0
  191. package/dist/recipes/tools/gmail.js.map +1 -0
  192. package/dist/recipes/tools/hubspot.d.ts +6 -0
  193. package/dist/recipes/tools/hubspot.js +232 -0
  194. package/dist/recipes/tools/hubspot.js.map +1 -0
  195. package/dist/recipes/tools/index.d.ts +22 -0
  196. package/dist/recipes/tools/index.js +25 -0
  197. package/dist/recipes/tools/index.js.map +1 -0
  198. package/dist/recipes/tools/intercom.d.ts +6 -0
  199. package/dist/recipes/tools/intercom.js +226 -0
  200. package/dist/recipes/tools/intercom.js.map +1 -0
  201. package/dist/recipes/tools/linear.d.ts +6 -0
  202. package/dist/recipes/tools/linear.js +83 -0
  203. package/dist/recipes/tools/linear.js.map +1 -0
  204. package/dist/recipes/tools/notion.d.ts +6 -0
  205. package/dist/recipes/tools/notion.js +278 -0
  206. package/dist/recipes/tools/notion.js.map +1 -0
  207. package/dist/recipes/tools/slack.d.ts +6 -0
  208. package/dist/recipes/tools/slack.js +72 -0
  209. package/dist/recipes/tools/slack.js.map +1 -0
  210. package/dist/recipes/tools/stripe.d.ts +6 -0
  211. package/dist/recipes/tools/stripe.js +265 -0
  212. package/dist/recipes/tools/stripe.js.map +1 -0
  213. package/dist/recipes/tools/zendesk.d.ts +6 -0
  214. package/dist/recipes/tools/zendesk.js +245 -0
  215. package/dist/recipes/tools/zendesk.js.map +1 -0
  216. package/dist/recipes/validation.d.ts +13 -0
  217. package/dist/recipes/validation.js +433 -0
  218. package/dist/recipes/validation.js.map +1 -0
  219. package/dist/recipes/yamlRunner.d.ts +87 -0
  220. package/dist/recipes/yamlRunner.js +693 -409
  221. package/dist/recipes/yamlRunner.js.map +1 -1
  222. package/dist/recipesHttp.d.ts +34 -6
  223. package/dist/recipesHttp.js +285 -15
  224. package/dist/recipesHttp.js.map +1 -1
  225. package/dist/riskTier.js +1 -0
  226. package/dist/riskTier.js.map +1 -1
  227. package/dist/runLog.d.ts +23 -0
  228. package/dist/runLog.js +56 -1
  229. package/dist/runLog.js.map +1 -1
  230. package/dist/schemas/dry-run-plan.v1.json +139 -0
  231. package/dist/schemas/recipe.v1.json +684 -0
  232. package/dist/server.d.ts +32 -1
  233. package/dist/server.js +980 -97
  234. package/dist/server.js.map +1 -1
  235. package/dist/streamableHttp.js +2 -0
  236. package/dist/streamableHttp.js.map +1 -1
  237. package/dist/tools/addLinearComment.d.ts +55 -0
  238. package/dist/tools/addLinearComment.js +72 -0
  239. package/dist/tools/addLinearComment.js.map +1 -0
  240. package/dist/tools/bridgeDoctor.js +2 -2
  241. package/dist/tools/bridgeDoctor.js.map +1 -1
  242. package/dist/tools/createLinearIssue.d.ts +84 -0
  243. package/dist/tools/createLinearIssue.js +146 -0
  244. package/dist/tools/createLinearIssue.js.map +1 -0
  245. package/dist/tools/fetchCalendarEvents.d.ts +94 -0
  246. package/dist/tools/fetchCalendarEvents.js +97 -0
  247. package/dist/tools/fetchCalendarEvents.js.map +1 -0
  248. package/dist/tools/fetchGithubIssue.d.ts +80 -0
  249. package/dist/tools/fetchGithubIssue.js +84 -0
  250. package/dist/tools/fetchGithubIssue.js.map +1 -0
  251. package/dist/tools/fetchGithubPR.d.ts +89 -0
  252. package/dist/tools/fetchGithubPR.js +96 -0
  253. package/dist/tools/fetchGithubPR.js.map +1 -0
  254. package/dist/tools/fetchSlackProfile.d.ts +43 -0
  255. package/dist/tools/fetchSlackProfile.js +46 -0
  256. package/dist/tools/fetchSlackProfile.js.map +1 -0
  257. package/dist/tools/getConnectorStatus.d.ts +58 -0
  258. package/dist/tools/getConnectorStatus.js +56 -0
  259. package/dist/tools/getConnectorStatus.js.map +1 -0
  260. package/dist/tools/github/actions.js +4 -2
  261. package/dist/tools/github/actions.js.map +1 -1
  262. package/dist/tools/github/composite.d.ts +339 -0
  263. package/dist/tools/github/composite.js +343 -0
  264. package/dist/tools/github/composite.js.map +1 -0
  265. package/dist/tools/github/index.d.ts +2 -1
  266. package/dist/tools/github/index.js +2 -1
  267. package/dist/tools/github/index.js.map +1 -1
  268. package/dist/tools/github/issues.js +8 -4
  269. package/dist/tools/github/issues.js.map +1 -1
  270. package/dist/tools/github/pr.d.ts +122 -0
  271. package/dist/tools/github/pr.js +195 -5
  272. package/dist/tools/github/pr.js.map +1 -1
  273. package/dist/tools/index.js +32 -1
  274. package/dist/tools/index.js.map +1 -1
  275. package/dist/tools/searchTools.js +1 -1
  276. package/dist/tools/searchTools.js.map +1 -1
  277. package/dist/tools/slackListChannels.d.ts +65 -0
  278. package/dist/tools/slackListChannels.js +70 -0
  279. package/dist/tools/slackListChannels.js.map +1 -0
  280. package/dist/tools/slackPostMessage.d.ts +57 -0
  281. package/dist/tools/slackPostMessage.js +77 -0
  282. package/dist/tools/slackPostMessage.js.map +1 -0
  283. package/dist/tools/testTraceToSource.js +2 -2
  284. package/dist/tools/testTraceToSource.js.map +1 -1
  285. package/dist/tools/updateLinearIssue.d.ts +89 -0
  286. package/dist/tools/updateLinearIssue.js +117 -0
  287. package/dist/tools/updateLinearIssue.js.map +1 -0
  288. package/dist/transport.d.ts +7 -1
  289. package/dist/transport.js +85 -11
  290. package/dist/transport.js.map +1 -1
  291. package/package.json +5 -2
  292. package/scripts/start-all.sh +56 -19
  293. package/templates/automation-policies/recipe-authoring.json +25 -0
  294. package/templates/automation-policy.example.json +6 -0
  295. package/templates/co.patchwork-os.bridge.plist +34 -0
  296. package/templates/recipes/ctx-loop-test.yaml +75 -0
  297. package/templates/recipes/lint-on-save.yaml +1 -2
  298. package/templates/recipes/morning-brief-slack.yaml +57 -0
  299. package/templates/recipes/morning-brief.yaml +14 -6
  300. package/templates/recipes/project-health-check.yaml +50 -0
  301. package/templates/recipes/sentry-to-linear.yaml +77 -0
@@ -0,0 +1,459 @@
1
+ /**
2
+ * Token Storage — secure credential storage for OAuth tokens.
3
+ *
4
+ * Platform-specific implementations:
5
+ * - macOS: Keychain (security command)
6
+ * - Windows: DPAPI (data protection API via PowerShell)
7
+ * - Linux: Secret Service API (via secret-tool or libsecret)
8
+ *
9
+ * Falls back to file-based encrypted storage if native APIs unavailable.
10
+ */
11
+ import { spawnSync } from "node:child_process";
12
+ import crypto from "node:crypto";
13
+ import { existsSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync, } from "node:fs";
14
+ import os from "node:os";
15
+ import { join } from "node:path";
16
+ const SERVICE_NAME = "patchwork-os";
17
+ function storageKey(provider) {
18
+ return `${SERVICE_NAME}.${provider}`;
19
+ }
20
+ function parseJson(json) {
21
+ if (json === null) {
22
+ return null;
23
+ }
24
+ try {
25
+ return JSON.parse(json);
26
+ }
27
+ catch {
28
+ return null;
29
+ }
30
+ }
31
+ export function storeSecretJsonSync(provider, value) {
32
+ const key = storageKey(provider);
33
+ const json = JSON.stringify(value);
34
+ if (resolveBackend() === "file") {
35
+ setEncryptedFileSync(key, json);
36
+ return;
37
+ }
38
+ if (setKeychainItemSync(key, json)) {
39
+ deleteEncryptedFileSync(key);
40
+ return;
41
+ }
42
+ setEncryptedFileSync(key, json);
43
+ }
44
+ export function getSecretJsonSync(provider) {
45
+ const key = storageKey(provider);
46
+ if (resolveBackend() === "file") {
47
+ return parseJson(getEncryptedFileSync(key));
48
+ }
49
+ const fromKeychain = getKeychainItemSync(key);
50
+ if (fromKeychain !== null) {
51
+ return parseJson(fromKeychain);
52
+ }
53
+ return parseJson(getEncryptedFileSync(key));
54
+ }
55
+ export function deleteSecretJsonSync(provider) {
56
+ const key = storageKey(provider);
57
+ if (resolveBackend() === "file") {
58
+ deleteEncryptedFileSync(key);
59
+ return;
60
+ }
61
+ deleteKeychainItemSync(key);
62
+ deleteEncryptedFileSync(key);
63
+ }
64
+ /**
65
+ * Store tokens securely for a provider.
66
+ */
67
+ export async function storeTokens(provider, tokens) {
68
+ storeSecretJsonSync(provider, tokens);
69
+ }
70
+ /**
71
+ * Retrieve stored tokens for a provider.
72
+ */
73
+ export async function getTokens(provider) {
74
+ return getSecretJsonSync(provider);
75
+ }
76
+ /**
77
+ * Delete stored tokens for a provider.
78
+ */
79
+ export async function deleteTokens(provider) {
80
+ deleteSecretJsonSync(provider);
81
+ }
82
+ /**
83
+ * List all providers with stored tokens.
84
+ */
85
+ export async function listStoredProviders() {
86
+ if (resolveBackend() === "file") {
87
+ return (await listEncryptedFiles()).sort();
88
+ }
89
+ const providers = [];
90
+ // Check keychain
91
+ const keychainProviders = await listKeychainItems();
92
+ providers.push(...keychainProviders);
93
+ // Check file storage
94
+ const fileProviders = await listEncryptedFiles();
95
+ for (const p of fileProviders) {
96
+ if (!providers.includes(p)) {
97
+ providers.push(p);
98
+ }
99
+ }
100
+ return providers.sort();
101
+ }
102
+ // Platform implementations are defined at the end of this file
103
+ // ============================================================================
104
+ // Windows DPAPI (via PowerShell)
105
+ // ============================================================================
106
+ function setWindowsCredentialSync(key, value) {
107
+ if (process.platform !== "win32")
108
+ return false;
109
+ try {
110
+ const script = `
111
+ $bytes = [System.Text.Encoding]::UTF8.GetBytes('${value.replace(/'/g, "''")}')
112
+ $protected = [System.Security.Cryptography.ProtectedData]::Protect($bytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
113
+ $path = Join-Path $env:LOCALAPPDATA "PatchworkOS" "tokens"
114
+ if (-not (Test-Path $path)) { New-Item -ItemType Directory -Path $path -Force | Out-Null }
115
+ $protected | Set-Content -Path (Join-Path $path "${key}.bin") -Encoding Byte
116
+ `;
117
+ const result = spawnSync("powershell", ["-Command", script], {
118
+ encoding: "utf-8",
119
+ timeout: 10000,
120
+ });
121
+ return result.status === 0;
122
+ }
123
+ catch {
124
+ return false;
125
+ }
126
+ }
127
+ function getWindowsCredentialSync(key) {
128
+ if (process.platform !== "win32")
129
+ return null;
130
+ try {
131
+ const script = `
132
+ $path = Join-Path $env:LOCALAPPDATA "PatchworkOS" "tokens" "${key}.bin"
133
+ if (Test-Path $path) {
134
+ $bytes = Get-Content -Path $path -Encoding Byte -Raw
135
+ $unprotected = [System.Security.Cryptography.ProtectedData]::Unprotect($bytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
136
+ [System.Text.Encoding]::UTF8.GetString($unprotected)
137
+ }
138
+ `;
139
+ const result = spawnSync("powershell", ["-Command", script], {
140
+ encoding: "utf-8",
141
+ timeout: 10000,
142
+ });
143
+ if (result.status !== 0) {
144
+ return null;
145
+ }
146
+ return result.stdout.trim() || null;
147
+ }
148
+ catch {
149
+ return null;
150
+ }
151
+ }
152
+ // ============================================================================
153
+ // Encrypted File Storage (Fallback)
154
+ // ============================================================================
155
+ function getStorageDir() {
156
+ const base = process.env.PATCHWORK_HOME ?? join(os.homedir(), ".patchwork");
157
+ return join(base, "tokens");
158
+ }
159
+ const MASTER_KEY_FILE = ".master.key";
160
+ let cachedKey = null;
161
+ let cachedKeyDir = null;
162
+ function legacyDerivedKey() {
163
+ // Legacy key: sha256(hostname + username). Kept only for one-time migration
164
+ // of existing encrypted files. New data is encrypted with the random master key.
165
+ const machineId = `${os.hostname()}-${os.userInfo().username}`;
166
+ return crypto.createHash("sha256").update(machineId).digest().slice(0, 32);
167
+ }
168
+ function getEncryptionKey() {
169
+ const dir = getStorageDir();
170
+ const keyPath = join(dir, MASTER_KEY_FILE);
171
+ if (cachedKey && cachedKeyDir === dir && existsSync(keyPath)) {
172
+ return cachedKey;
173
+ }
174
+ if (existsSync(keyPath)) {
175
+ try {
176
+ const key = readFileSync(keyPath);
177
+ if (key.length === 32) {
178
+ cachedKey = key;
179
+ cachedKeyDir = dir;
180
+ return key;
181
+ }
182
+ }
183
+ catch {
184
+ // fall through to regenerate
185
+ }
186
+ // Corrupt or unreadable — replace.
187
+ try {
188
+ unlinkSync(keyPath);
189
+ }
190
+ catch { }
191
+ }
192
+ if (!existsSync(dir)) {
193
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
194
+ }
195
+ const key = crypto.randomBytes(32);
196
+ try {
197
+ // flag "wx" = O_EXCL: fail if another process created the file in between.
198
+ writeFileSync(keyPath, key, { flag: "wx", mode: 0o600 });
199
+ }
200
+ catch {
201
+ // Another process may have written it first; prefer that one for consistency.
202
+ try {
203
+ const existing = readFileSync(keyPath);
204
+ if (existing.length === 32) {
205
+ cachedKey = existing;
206
+ cachedKeyDir = dir;
207
+ return existing;
208
+ }
209
+ }
210
+ catch { }
211
+ // Best effort: fall through with the in-memory key.
212
+ }
213
+ cachedKey = key;
214
+ cachedKeyDir = dir;
215
+ return key;
216
+ }
217
+ function encrypt(text) {
218
+ const iv = crypto.randomBytes(16);
219
+ const cipher = crypto.createCipheriv("aes-256-gcm", getEncryptionKey(), iv);
220
+ let encrypted = cipher.update(text, "utf8", "hex");
221
+ encrypted += cipher.final("hex");
222
+ const authTag = cipher.getAuthTag();
223
+ return `${iv.toString("hex")}:${authTag.toString("hex")}:${encrypted}`;
224
+ }
225
+ function decryptWith(key, encryptedData) {
226
+ try {
227
+ const [ivHex, authTagHex, encrypted] = encryptedData.split(":");
228
+ if (!ivHex || !authTagHex || !encrypted)
229
+ return null;
230
+ const decipher = crypto.createDecipheriv("aes-256-gcm", key, Buffer.from(ivHex, "hex"));
231
+ decipher.setAuthTag(Buffer.from(authTagHex, "hex"));
232
+ let decrypted = decipher.update(encrypted, "hex", "utf8");
233
+ decrypted += decipher.final("utf8");
234
+ return decrypted;
235
+ }
236
+ catch {
237
+ return null;
238
+ }
239
+ }
240
+ function decrypt(encryptedData) {
241
+ return decryptWith(getEncryptionKey(), encryptedData);
242
+ }
243
+ function setEncryptedFileSync(key, value) {
244
+ const dir = getStorageDir();
245
+ if (!existsSync(dir)) {
246
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
247
+ }
248
+ const encrypted = encrypt(value);
249
+ writeFileSync(join(dir, `${key}.enc`), encrypted, { mode: 0o600 });
250
+ }
251
+ function getEncryptedFileSync(key) {
252
+ const filePath = join(getStorageDir(), `${key}.enc`);
253
+ if (!existsSync(filePath))
254
+ return null;
255
+ try {
256
+ const encrypted = readFileSync(filePath, "utf-8");
257
+ const plain = decrypt(encrypted);
258
+ if (plain !== null)
259
+ return plain;
260
+ // One-time migration: files encrypted with the old hostname-derived key
261
+ // are re-encrypted under the random master key.
262
+ const legacyPlain = decryptWith(legacyDerivedKey(), encrypted);
263
+ if (legacyPlain !== null) {
264
+ setEncryptedFileSync(key, legacyPlain);
265
+ return legacyPlain;
266
+ }
267
+ return null;
268
+ }
269
+ catch {
270
+ return null;
271
+ }
272
+ }
273
+ function deleteEncryptedFileSync(key) {
274
+ const filePath = join(getStorageDir(), `${key}.enc`);
275
+ if (existsSync(filePath)) {
276
+ try {
277
+ unlinkSync(filePath);
278
+ }
279
+ catch { }
280
+ }
281
+ }
282
+ function listEncryptedFiles() {
283
+ const dir = getStorageDir();
284
+ if (!existsSync(dir))
285
+ return [];
286
+ try {
287
+ const files = readdirSync(dir);
288
+ return files
289
+ .filter((f) => f.endsWith(".enc"))
290
+ .map((f) => f.replace(`${SERVICE_NAME}.`, "").replace(".enc", ""));
291
+ }
292
+ catch {
293
+ return [];
294
+ }
295
+ }
296
+ function deleteWindowsCredentialSync(key) {
297
+ if (process.platform !== "win32")
298
+ return false;
299
+ try {
300
+ const localAppData = process.env.LOCALAPPDATA;
301
+ if (!localAppData)
302
+ return false;
303
+ const filePath = join(localAppData, "PatchworkOS", "tokens", `${key}.bin`);
304
+ if (!existsSync(filePath))
305
+ return true;
306
+ unlinkSync(filePath);
307
+ return true;
308
+ }
309
+ catch {
310
+ return false;
311
+ }
312
+ }
313
+ // ============================================================================
314
+ // Helpers
315
+ // ============================================================================
316
+ function resolveBackend() {
317
+ const backend = process.env.PATCHWORK_TOKEN_STORAGE_BACKEND;
318
+ if (backend === "file" || backend === "native" || backend === "auto") {
319
+ return backend;
320
+ }
321
+ return "auto";
322
+ }
323
+ // Platform abstraction
324
+ function setKeychainItemSync(key, value) {
325
+ if (process.platform === "darwin") {
326
+ return setMacOSKeychainItemSync(key, value);
327
+ }
328
+ if (process.platform === "win32") {
329
+ return setWindowsCredentialSync(key, value);
330
+ }
331
+ return setLinuxSecretSync(key, value);
332
+ }
333
+ function getKeychainItemSync(key) {
334
+ if (process.platform === "darwin") {
335
+ return getMacOSKeychainItemSync(key);
336
+ }
337
+ if (process.platform === "win32") {
338
+ return getWindowsCredentialSync(key);
339
+ }
340
+ return getLinuxSecretSync(key);
341
+ }
342
+ function deleteKeychainItemSync(key) {
343
+ if (process.platform === "darwin") {
344
+ return deleteMacOSKeychainItemSync(key);
345
+ }
346
+ if (process.platform === "win32") {
347
+ return deleteWindowsCredentialSync(key);
348
+ }
349
+ return deleteLinuxSecretSync(key);
350
+ }
351
+ function listKeychainItems() {
352
+ if (process.platform === "darwin") {
353
+ return listMacOSKeychainItems();
354
+ }
355
+ if (process.platform === "win32") {
356
+ // Handled by file listing
357
+ return [];
358
+ }
359
+ return listLinuxSecrets();
360
+ }
361
+ // Linux Secret Service
362
+ function setLinuxSecretSync(key, value) {
363
+ try {
364
+ const result = spawnSync("secret-tool", ["store", "--label", key, "service", SERVICE_NAME, "account", key], { input: value, encoding: "utf-8", timeout: 5000 });
365
+ return result.status === 0;
366
+ }
367
+ catch {
368
+ return false;
369
+ }
370
+ }
371
+ function getLinuxSecretSync(key) {
372
+ try {
373
+ const result = spawnSync("secret-tool", ["lookup", "service", SERVICE_NAME, "account", key], { encoding: "utf-8", timeout: 5000 });
374
+ if (result.status === 0 && result.stdout) {
375
+ return result.stdout.trim();
376
+ }
377
+ return null;
378
+ }
379
+ catch {
380
+ return null;
381
+ }
382
+ }
383
+ function deleteLinuxSecretSync(key) {
384
+ try {
385
+ const result = spawnSync("secret-tool", ["clear", "service", SERVICE_NAME, "account", key], { encoding: "utf-8", timeout: 5000 });
386
+ return result.status === 0;
387
+ }
388
+ catch {
389
+ return false;
390
+ }
391
+ }
392
+ function listLinuxSecrets() {
393
+ // secret-tool doesn't have a list command; we'd need libsecret bindings
394
+ return [];
395
+ }
396
+ // Rename the platform-specific functions to avoid conflicts
397
+ function setMacOSKeychainItemSync(key, value) {
398
+ try {
399
+ const result = spawnSync("security", [
400
+ "add-generic-password",
401
+ "-s",
402
+ key,
403
+ "-a",
404
+ SERVICE_NAME,
405
+ "-w",
406
+ value,
407
+ "-U",
408
+ ], { encoding: "utf-8", timeout: 5000 });
409
+ return result.status === 0;
410
+ }
411
+ catch {
412
+ return false;
413
+ }
414
+ }
415
+ function getMacOSKeychainItemSync(key) {
416
+ try {
417
+ const result = spawnSync("security", ["find-generic-password", "-s", key, "-a", SERVICE_NAME, "-w"], { encoding: "utf-8", timeout: 5000 });
418
+ if (result.status === 0 && result.stdout) {
419
+ return result.stdout.trim();
420
+ }
421
+ return null;
422
+ }
423
+ catch {
424
+ return null;
425
+ }
426
+ }
427
+ function deleteMacOSKeychainItemSync(key) {
428
+ try {
429
+ const result = spawnSync("security", ["delete-generic-password", "-s", key, "-a", SERVICE_NAME], { encoding: "utf-8", timeout: 5000 });
430
+ return result.status === 0;
431
+ }
432
+ catch {
433
+ return false;
434
+ }
435
+ }
436
+ function listMacOSKeychainItems() {
437
+ try {
438
+ const result = spawnSync("security", ["dump-keychain"], {
439
+ encoding: "utf-8",
440
+ timeout: 10000,
441
+ });
442
+ if (result.status !== 0)
443
+ return [];
444
+ const providers = [];
445
+ const regex = new RegExp(`svce<blob>=${SERVICE_NAME}\\.([^\\s]+)`, "g");
446
+ let match;
447
+ while ((match = regex.exec(result.stdout)) !== null) {
448
+ const provider = match[1];
449
+ if (provider) {
450
+ providers.push(provider);
451
+ }
452
+ }
453
+ return providers;
454
+ }
455
+ catch {
456
+ return [];
457
+ }
458
+ }
459
+ //# sourceMappingURL=tokenStorage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenStorage.js","sourceRoot":"","sources":["../../src/connectors/tokenStorage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Zendesk connector — read/write Zendesk tickets via the Zendesk REST API v2.
3
+ *
4
+ * Auth: API token + email + subdomain.
5
+ * - Env vars: ZENDESK_API_TOKEN, ZENDESK_EMAIL, ZENDESK_SUBDOMAIN
6
+ * - Stored: getSecretJsonSync("zendesk") → ZendeskTokens
7
+ * - Basic auth: `email/token:api_token` (Zendesk token auth convention)
8
+ *
9
+ * Tools: listTickets, getTicket, addComment, updateStatus, listUsers
10
+ *
11
+ * Extends BaseConnector for unified auth, retry, rate-limit, error handling.
12
+ */
13
+ import { type AuthContext, BaseConnector, type ConnectorError, type ConnectorStatus } from "./baseConnector.js";
14
+ export interface ZendeskTokens {
15
+ apiToken: string;
16
+ email: string;
17
+ subdomain: string;
18
+ connected_at: string;
19
+ }
20
+ export interface ZendeskTicket {
21
+ id: number;
22
+ subject: string;
23
+ description: string;
24
+ status: "new" | "open" | "pending" | "hold" | "solved" | "closed";
25
+ priority: "urgent" | "high" | "normal" | "low" | null;
26
+ type: "problem" | "incident" | "question" | "task" | null;
27
+ requester_id: number;
28
+ assignee_id: number | null;
29
+ group_id: number | null;
30
+ tags: string[];
31
+ created_at: string;
32
+ updated_at: string;
33
+ url: string;
34
+ }
35
+ export interface ZendeskComment {
36
+ id: number;
37
+ type: "Comment" | "VoiceComment";
38
+ author_id: number;
39
+ body: string;
40
+ html_body: string;
41
+ public: boolean;
42
+ created_at: string;
43
+ }
44
+ export interface ZendeskUser {
45
+ id: number;
46
+ name: string;
47
+ email: string;
48
+ role: "end-user" | "agent" | "admin";
49
+ active: boolean;
50
+ created_at: string;
51
+ }
52
+ export interface ZendeskListResult<T> {
53
+ results: T[];
54
+ count: number;
55
+ next_page: string | null;
56
+ previous_page: string | null;
57
+ }
58
+ export declare class ZendeskConnector extends BaseConnector {
59
+ readonly providerName = "zendesk";
60
+ private tokens;
61
+ protected getOAuthConfig(): null;
62
+ authenticate(): Promise<AuthContext>;
63
+ healthCheck(): Promise<{
64
+ ok: boolean;
65
+ error?: ConnectorError;
66
+ }>;
67
+ normalizeError(error: unknown): ConnectorError;
68
+ getStatus(): ConnectorStatus;
69
+ listTickets(params?: {
70
+ status?: ZendeskTicket["status"];
71
+ assigneeId?: number;
72
+ query?: string;
73
+ perPage?: number;
74
+ }): Promise<ZendeskListResult<ZendeskTicket>>;
75
+ getTicket(ticketId: number): Promise<ZendeskTicket | null>;
76
+ getTicketComments(ticketId: number): Promise<ZendeskComment[]>;
77
+ addComment(ticketId: number, body: string, isPublic?: boolean): Promise<ZendeskTicket>;
78
+ updateStatus(ticketId: number, status: ZendeskTicket["status"]): Promise<ZendeskTicket>;
79
+ listUsers(role?: ZendeskUser["role"], perPage?: number): Promise<ZendeskUser[]>;
80
+ private baseUrl;
81
+ private buildHeaders;
82
+ }
83
+ export declare function loadTokens(): ZendeskTokens | null;
84
+ export declare function saveTokens(tokens: ZendeskTokens): void;
85
+ export declare function clearTokens(): void;
86
+ export declare function getZendeskConnector(): ZendeskConnector;
87
+ export { getZendeskConnector as zendesk };
88
+ export interface ConnectorHandlerResult {
89
+ status: number;
90
+ body: string;
91
+ contentType?: string;
92
+ }
93
+ /**
94
+ * POST /connections/zendesk/connect { apiToken, email, subdomain }
95
+ */
96
+ export declare function handleZendeskConnect(body: string): Promise<ConnectorHandlerResult>;
97
+ /**
98
+ * POST /connections/zendesk/test
99
+ */
100
+ export declare function handleZendeskTest(): Promise<ConnectorHandlerResult>;
101
+ /**
102
+ * DELETE /connections/zendesk
103
+ */
104
+ export declare function handleZendeskDisconnect(): ConnectorHandlerResult;