patchwork-os 0.2.0-alpha.34 → 0.2.0-alpha.35
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.
- package/README.md +142 -88
- package/deploy/bootstrap-new-vps.sh +12 -12
- package/deploy/bootstrap-vps.sh +6 -3
- package/deploy/deploy-landing.sh +59 -2
- package/dist/bridge.js +32 -1
- package/dist/bridge.js.map +1 -1
- package/dist/commands/recipe.js +18 -1
- package/dist/commands/recipe.js.map +1 -1
- package/dist/commands/recipeInstall.d.ts +79 -1
- package/dist/commands/recipeInstall.js +241 -13
- package/dist/commands/recipeInstall.js.map +1 -1
- package/dist/connectors/asana.d.ts +198 -0
- package/dist/connectors/asana.js +680 -0
- package/dist/connectors/asana.js.map +1 -0
- package/dist/connectors/baseConnector.d.ts +16 -0
- package/dist/connectors/baseConnector.js +106 -24
- package/dist/connectors/baseConnector.js.map +1 -1
- package/dist/connectors/discord.d.ts +150 -0
- package/dist/connectors/discord.js +544 -0
- package/dist/connectors/discord.js.map +1 -0
- package/dist/connectors/github.js +11 -4
- package/dist/connectors/github.js.map +1 -1
- package/dist/connectors/gitlab.d.ts +180 -0
- package/dist/connectors/gitlab.js +582 -0
- package/dist/connectors/gitlab.js.map +1 -0
- package/dist/connectors/gmail.js +11 -0
- package/dist/connectors/gmail.js.map +1 -1
- package/dist/connectors/googleDrive.d.ts +34 -0
- package/dist/connectors/googleDrive.js +305 -0
- package/dist/connectors/googleDrive.js.map +1 -0
- package/dist/connectors/linear.js +23 -4
- package/dist/connectors/linear.js.map +1 -1
- package/dist/connectors/pagerduty.d.ts +160 -0
- package/dist/connectors/pagerduty.js +464 -0
- package/dist/connectors/pagerduty.js.map +1 -0
- package/dist/connectors/slack.d.ts +1 -1
- package/dist/connectors/slack.js +3 -1
- package/dist/connectors/slack.js.map +1 -1
- package/dist/featureFlags.d.ts +17 -11
- package/dist/featureFlags.js +52 -47
- package/dist/featureFlags.js.map +1 -1
- package/dist/index.js +255 -127
- package/dist/index.js.map +1 -1
- package/dist/recipeOrchestration.d.ts +7 -0
- package/dist/recipeOrchestration.js +149 -28
- package/dist/recipeOrchestration.js.map +1 -1
- package/dist/recipes/captureForRunlog.d.ts +27 -0
- package/dist/recipes/captureForRunlog.js +128 -0
- package/dist/recipes/captureForRunlog.js.map +1 -0
- package/dist/recipes/chainedRunner.d.ts +39 -3
- package/dist/recipes/chainedRunner.js +183 -28
- package/dist/recipes/chainedRunner.js.map +1 -1
- package/dist/recipes/detectSilentFail.d.ts +34 -0
- package/dist/recipes/detectSilentFail.js +105 -0
- package/dist/recipes/detectSilentFail.js.map +1 -0
- package/dist/recipes/manifest.js +21 -6
- package/dist/recipes/manifest.js.map +1 -1
- package/dist/recipes/replayRun.d.ts +62 -0
- package/dist/recipes/replayRun.js +97 -0
- package/dist/recipes/replayRun.js.map +1 -0
- package/dist/recipes/scheduler.js +102 -11
- package/dist/recipes/scheduler.js.map +1 -1
- package/dist/recipes/schemaGenerator.js +3 -3
- package/dist/recipes/schemaGenerator.js.map +1 -1
- package/dist/recipes/toolRegistry.d.ts +5 -0
- package/dist/recipes/toolRegistry.js +9 -0
- package/dist/recipes/toolRegistry.js.map +1 -1
- package/dist/recipes/tools/asana.d.ts +16 -0
- package/dist/recipes/tools/asana.js +524 -0
- package/dist/recipes/tools/asana.js.map +1 -0
- package/dist/recipes/tools/discord.d.ts +18 -0
- package/dist/recipes/tools/discord.js +254 -0
- package/dist/recipes/tools/discord.js.map +1 -0
- package/dist/recipes/tools/github.js +29 -4
- package/dist/recipes/tools/github.js.map +1 -1
- package/dist/recipes/tools/gitlab.d.ts +11 -0
- package/dist/recipes/tools/gitlab.js +285 -0
- package/dist/recipes/tools/gitlab.js.map +1 -0
- package/dist/recipes/tools/gmail.d.ts +1 -1
- package/dist/recipes/tools/gmail.js +230 -6
- package/dist/recipes/tools/gmail.js.map +1 -1
- package/dist/recipes/tools/googleDrive.d.ts +1 -0
- package/dist/recipes/tools/googleDrive.js +55 -0
- package/dist/recipes/tools/googleDrive.js.map +1 -0
- package/dist/recipes/tools/index.d.ts +6 -0
- package/dist/recipes/tools/index.js +6 -0
- package/dist/recipes/tools/index.js.map +1 -1
- package/dist/recipes/tools/linear.d.ts +2 -1
- package/dist/recipes/tools/linear.js +222 -1
- package/dist/recipes/tools/linear.js.map +1 -1
- package/dist/recipes/tools/meetingNotes.d.ts +21 -0
- package/dist/recipes/tools/meetingNotes.js +701 -0
- package/dist/recipes/tools/meetingNotes.js.map +1 -0
- package/dist/recipes/tools/pagerduty.d.ts +15 -0
- package/dist/recipes/tools/pagerduty.js +451 -0
- package/dist/recipes/tools/pagerduty.js.map +1 -0
- package/dist/recipes/tools/slack.js +8 -2
- package/dist/recipes/tools/slack.js.map +1 -1
- package/dist/recipes/yamlRunner.d.ts +23 -2
- package/dist/recipes/yamlRunner.js +263 -58
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/recipesHttp.d.ts +32 -0
- package/dist/recipesHttp.js +310 -1
- package/dist/recipesHttp.js.map +1 -1
- package/dist/runLog.d.ts +64 -2
- package/dist/runLog.js +116 -2
- package/dist/runLog.js.map +1 -1
- package/dist/server.d.ts +8 -0
- package/dist/server.js +331 -9
- package/dist/server.js.map +1 -1
- package/dist/streamableHttp.d.ts +31 -1
- package/dist/streamableHttp.js +20 -2
- package/dist/streamableHttp.js.map +1 -1
- package/dist/tools/slackPostMessage.js +1 -1
- package/dist/tools/slackPostMessage.js.map +1 -1
- package/package.json +19 -4
- package/templates/recipes/project-health-check.yaml +1 -1
|
@@ -8,22 +8,56 @@
|
|
|
8
8
|
* https://github.com/owner/repo
|
|
9
9
|
* ./local/path
|
|
10
10
|
*/
|
|
11
|
-
import { cpSync, existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync, } from "node:fs";
|
|
11
|
+
import { cpSync, existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
12
12
|
import https from "node:https";
|
|
13
13
|
import os from "node:os";
|
|
14
14
|
import path from "node:path";
|
|
15
15
|
import { getManifestRecipeFiles, loadManifestFromDir, parseManifest, } from "../recipes/manifest.js";
|
|
16
16
|
export const INSTALL_RECIPES_DIR = path.join(os.homedir(), ".patchwork", "recipes");
|
|
17
|
+
/**
|
|
18
|
+
* Marker file written into a recipe install dir to mark it as disabled.
|
|
19
|
+
* Absence = enabled (the default for legacy installs predating this marker).
|
|
20
|
+
* `runRecipeInstall` writes one on every fresh install so new recipes start
|
|
21
|
+
* disabled per the wave2 plan's safety story; user runs `patchwork recipe
|
|
22
|
+
* enable <name>` to remove it.
|
|
23
|
+
*/
|
|
24
|
+
const DISABLED_MARKER = ".disabled";
|
|
25
|
+
/**
|
|
26
|
+
* Reject path components that aren't a single safe basename — used at every
|
|
27
|
+
* boundary where externally-sourced filenames are joined onto a trusted
|
|
28
|
+
* directory (manifest fields, GitHub API responses, CLI args).
|
|
29
|
+
*
|
|
30
|
+
* Rejects empty/".."/".", any path separator, and control chars (NUL/newline/tab).
|
|
31
|
+
* Exported for testing and reuse.
|
|
32
|
+
*/
|
|
33
|
+
export function isSafeBasename(name) {
|
|
34
|
+
if (typeof name !== "string" || name.length === 0)
|
|
35
|
+
return false;
|
|
36
|
+
if (name === "." || name === "..")
|
|
37
|
+
return false;
|
|
38
|
+
if (name.includes("/") || name.includes("\\"))
|
|
39
|
+
return false;
|
|
40
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: explicit control-char check
|
|
41
|
+
if (/[\x00-\x1F\x7F]/.test(name))
|
|
42
|
+
return false;
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
17
45
|
/**
|
|
18
46
|
* Parse a user-supplied source string into a typed InstallSource.
|
|
19
47
|
*
|
|
20
48
|
* Supported forms:
|
|
21
49
|
* github:owner/repo
|
|
50
|
+
* github:owner/repo@<ref> — pin to branch, tag, or commit SHA
|
|
22
51
|
* github:owner/repo/subdir
|
|
52
|
+
* github:owner/repo/subdir@<ref>
|
|
53
|
+
* gh:owner/repo[@<ref>] — short alias for github:
|
|
23
54
|
* https://github.com/owner/repo
|
|
24
|
-
* https://github.com/owner/repo/tree
|
|
55
|
+
* https://github.com/owner/repo/tree/<ref>/subdir — ref captured from URL
|
|
25
56
|
* ./relative/path
|
|
26
57
|
* /absolute/path
|
|
58
|
+
*
|
|
59
|
+
* `@<ref>` accepts any value that's valid as a git ref (branch, tag, SHA).
|
|
60
|
+
* Empty ref (`...@`) is rejected.
|
|
27
61
|
*/
|
|
28
62
|
export function parseInstallSource(source) {
|
|
29
63
|
// Local path: starts with . or /
|
|
@@ -32,28 +66,44 @@ export function parseInstallSource(source) {
|
|
|
32
66
|
source.startsWith("../")) {
|
|
33
67
|
return { type: "local", path: source };
|
|
34
68
|
}
|
|
35
|
-
// github: prefix
|
|
69
|
+
// github:/gh: prefix
|
|
36
70
|
if (source.startsWith("github:")) {
|
|
37
71
|
return parseGithubShorthand(source.slice("github:".length));
|
|
38
72
|
}
|
|
39
|
-
|
|
40
|
-
|
|
73
|
+
if (source.startsWith("gh:")) {
|
|
74
|
+
return parseGithubShorthand(source.slice("gh:".length));
|
|
75
|
+
}
|
|
76
|
+
// Full GitHub URL — captures owner, repo, optional ref (tree/<ref>), optional subdir
|
|
77
|
+
const githubUrlMatch = source.match(/^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/tree\/([^/]+)(?:\/(.+))?)?\/?$/);
|
|
41
78
|
if (githubUrlMatch) {
|
|
42
|
-
const [, owner, repo, subdir] = githubUrlMatch;
|
|
79
|
+
const [, owner, repo, ref, subdir] = githubUrlMatch;
|
|
43
80
|
if (!owner || !repo) {
|
|
44
81
|
throw new Error(`Invalid GitHub URL: ${source}`);
|
|
45
82
|
}
|
|
46
83
|
return {
|
|
47
84
|
type: "github",
|
|
48
85
|
owner,
|
|
49
|
-
repo
|
|
86
|
+
repo,
|
|
50
87
|
...(subdir ? { subdir } : {}),
|
|
88
|
+
...(ref ? { ref } : {}),
|
|
51
89
|
};
|
|
52
90
|
}
|
|
53
91
|
throw new Error(`Unrecognized install source: "${source}"\n` +
|
|
54
|
-
`Supported: github:owner/repo, github:owner/repo/subdir, https://github.com/owner/repo, ./local/path`);
|
|
92
|
+
`Supported: github:owner/repo[@ref], github:owner/repo/subdir[@ref], gh:owner/repo[@ref], https://github.com/owner/repo, ./local/path`);
|
|
55
93
|
}
|
|
56
94
|
function parseGithubShorthand(shorthand) {
|
|
95
|
+
// Extract trailing @<ref> if present. The ref is opaque to us — git accepts
|
|
96
|
+
// branches, tags, and commit SHAs in the same slot, and the GitHub API
|
|
97
|
+
// (which is what we ultimately call with this value) does too.
|
|
98
|
+
let ref;
|
|
99
|
+
const atIdx = shorthand.lastIndexOf("@");
|
|
100
|
+
if (atIdx !== -1) {
|
|
101
|
+
ref = shorthand.slice(atIdx + 1);
|
|
102
|
+
shorthand = shorthand.slice(0, atIdx);
|
|
103
|
+
if (!ref) {
|
|
104
|
+
throw new Error(`Invalid github shorthand: empty ref after "@" in "${shorthand}@"`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
57
107
|
// owner/repo or owner/repo/subdir (may have multiple path segments)
|
|
58
108
|
const parts = shorthand.split("/");
|
|
59
109
|
if (parts.length < 2) {
|
|
@@ -68,6 +118,7 @@ function parseGithubShorthand(shorthand) {
|
|
|
68
118
|
owner,
|
|
69
119
|
repo,
|
|
70
120
|
...(subdirParts.length > 0 ? { subdir: subdirParts.join("/") } : {}),
|
|
121
|
+
...(ref ? { ref } : {}),
|
|
71
122
|
};
|
|
72
123
|
}
|
|
73
124
|
// ============================================================================
|
|
@@ -149,8 +200,20 @@ async function downloadGitHubDir(owner, repo, dirPath, ref, destDir) {
|
|
|
149
200
|
}
|
|
150
201
|
if (!item.download_url)
|
|
151
202
|
continue;
|
|
203
|
+
// GitHub Contents API responses are not implicitly trusted: a hostile
|
|
204
|
+
// repo (or a redirect-to-attacker) could supply names like `../etc/x`.
|
|
205
|
+
// The existing extension filter above already blocks the most obvious
|
|
206
|
+
// payloads, but we explicitly reject anything that isn't a single
|
|
207
|
+
// basename so a future change to the filter doesn't reopen the gap.
|
|
208
|
+
if (!isSafeBasename(item.name)) {
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
152
211
|
const content = await fetchGitHubFile(item.download_url);
|
|
153
212
|
const destPath = path.join(destDir, item.name);
|
|
213
|
+
// Belt-and-suspenders: confirm the resolved write path lives inside destDir.
|
|
214
|
+
if (!path.resolve(destPath).startsWith(`${path.resolve(destDir)}${path.sep}`)) {
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
154
217
|
writeFileSync(destPath, content);
|
|
155
218
|
written.push(item.name);
|
|
156
219
|
}
|
|
@@ -195,9 +258,25 @@ export async function runRecipeInstall(rawSource, options = {}) {
|
|
|
195
258
|
}
|
|
196
259
|
const installName = determineInstallName(manifest, source);
|
|
197
260
|
const installDir = path.join(recipesDir, installName);
|
|
198
|
-
|
|
199
|
-
|
|
261
|
+
// Reinstall correctness: detect whether this is an upgrade in place,
|
|
262
|
+
// and snapshot the existing enabled state so the upgrade doesn't
|
|
263
|
+
// silently re-disable a recipe the user explicitly opted into.
|
|
264
|
+
const isReinstall = existsSync(installDir);
|
|
265
|
+
const wasEnabled = isReinstall
|
|
266
|
+
? !existsSync(path.join(installDir, DISABLED_MARKER))
|
|
267
|
+
: false;
|
|
268
|
+
if (isReinstall) {
|
|
269
|
+
// Clear stale files from the previous version so files dropped from
|
|
270
|
+
// the new manifest don't linger. We rebuild the install dir wholesale
|
|
271
|
+
// rather than overlay the new files on top of the old.
|
|
272
|
+
try {
|
|
273
|
+
rmSync(installDir, { recursive: true, force: true });
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
// best-effort; mkdirSync below will throw with a clearer error
|
|
277
|
+
}
|
|
200
278
|
}
|
|
279
|
+
mkdirSync(installDir, { recursive: true });
|
|
201
280
|
// Copy files
|
|
202
281
|
for (const file of filesToCopy) {
|
|
203
282
|
const src = path.join(tmpDir, file);
|
|
@@ -209,6 +288,14 @@ export async function runRecipeInstall(rawSource, options = {}) {
|
|
|
209
288
|
}
|
|
210
289
|
cpSync(src, dest);
|
|
211
290
|
}
|
|
291
|
+
// Write the disabled-marker policy:
|
|
292
|
+
// - Fresh install: start disabled (per the wave2 plan's safety story).
|
|
293
|
+
// - Reinstall (upgrade in place): preserve whatever the user had set.
|
|
294
|
+
// If the recipe was enabled before, leave it enabled; if disabled,
|
|
295
|
+
// leave it disabled. Don't silently revoke an explicit user opt-in.
|
|
296
|
+
if (!isReinstall || !wasEnabled) {
|
|
297
|
+
writeFileSync(path.join(installDir, DISABLED_MARKER), "");
|
|
298
|
+
}
|
|
212
299
|
return {
|
|
213
300
|
name: installName,
|
|
214
301
|
version: manifest?.version,
|
|
@@ -256,6 +343,143 @@ async function stageGitHubSource(source, tmpDir) {
|
|
|
256
343
|
throw err;
|
|
257
344
|
}
|
|
258
345
|
}
|
|
346
|
+
/**
|
|
347
|
+
* Returns true if the install dir does not contain the disabled marker.
|
|
348
|
+
* Recipes installed before this marker existed have no marker and are
|
|
349
|
+
* therefore considered enabled — preserves backwards compatibility.
|
|
350
|
+
*/
|
|
351
|
+
export function isRecipeEnabled(installDir) {
|
|
352
|
+
return !existsSync(path.join(installDir, DISABLED_MARKER));
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Locate an installed recipe directory by name. Returns null if not found.
|
|
356
|
+
*
|
|
357
|
+
* Validates `name` is a safe basename to defend against `recipe enable
|
|
358
|
+
* ../../../etc/foo` and similar — even though the on-disk effect would be
|
|
359
|
+
* limited to the `.disabled` filename, an arbitrary-path file write under
|
|
360
|
+
* the user's privilege is still a real attack surface.
|
|
361
|
+
*/
|
|
362
|
+
function findInstalledRecipeDir(name, recipesDir) {
|
|
363
|
+
if (!isSafeBasename(name)) {
|
|
364
|
+
throw new Error(`Invalid recipe name "${name}" — must be a single directory name without path separators or control characters.`);
|
|
365
|
+
}
|
|
366
|
+
const direct = path.join(recipesDir, name);
|
|
367
|
+
// Defense-in-depth: even with the basename check above, confirm the resolved
|
|
368
|
+
// path lives under recipesDir. Symlinks inside recipesDir could in principle
|
|
369
|
+
// escape, so this catches that too.
|
|
370
|
+
const resolvedRoot = path.resolve(recipesDir);
|
|
371
|
+
const resolvedDir = path.resolve(direct);
|
|
372
|
+
if (!resolvedDir.startsWith(`${resolvedRoot}${path.sep}`)) {
|
|
373
|
+
throw new Error(`Resolved recipe path escapes recipes directory: "${name}"`);
|
|
374
|
+
}
|
|
375
|
+
if (existsSync(direct) && statSync(direct).isDirectory()) {
|
|
376
|
+
return direct;
|
|
377
|
+
}
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Resolve an install-dir-name (the directory `runRecipeInstall` created) to
|
|
382
|
+
* the YAML entrypoint inside it. Used by `recipe run <name>` so the user can
|
|
383
|
+
* pass the name they see in `recipe list` rather than having to dig into the
|
|
384
|
+
* install directory layout.
|
|
385
|
+
*
|
|
386
|
+
* Resolution order:
|
|
387
|
+
* 1. `recipe.json` manifest's `recipes.main`, if the manifest exists and
|
|
388
|
+
* the file it points at exists on disk.
|
|
389
|
+
* 2. First `*.yaml` / `*.yml` in the install dir.
|
|
390
|
+
*
|
|
391
|
+
* Returns null if `name` doesn't correspond to an install dir, or the dir
|
|
392
|
+
* exists but contains no resolvable entrypoint. Path-traversal `name` values
|
|
393
|
+
* (e.g. `../../etc`) throw via the underlying `findInstalledRecipeDir` —
|
|
394
|
+
* same defence as enable/disable/uninstall.
|
|
395
|
+
*/
|
|
396
|
+
export function findInstalledRecipeEntrypoint(name, options = {}) {
|
|
397
|
+
const recipesDir = options.recipesDir ?? INSTALL_RECIPES_DIR;
|
|
398
|
+
const installDir = findInstalledRecipeDir(name, recipesDir);
|
|
399
|
+
if (!installDir)
|
|
400
|
+
return null;
|
|
401
|
+
const manifestPath = path.join(installDir, "recipe.json");
|
|
402
|
+
if (existsSync(manifestPath)) {
|
|
403
|
+
try {
|
|
404
|
+
const m = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
405
|
+
if (m.recipes?.main && isSafeBasename(m.recipes.main)) {
|
|
406
|
+
const candidate = path.join(installDir, m.recipes.main);
|
|
407
|
+
if (existsSync(candidate))
|
|
408
|
+
return candidate;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
catch {
|
|
412
|
+
// Malformed manifest → fall through to first-yaml lookup. The
|
|
413
|
+
// scheduler does the same; surfacing the parse error here would
|
|
414
|
+
// shadow the top-level "recipe not found" error from the CLI.
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
try {
|
|
418
|
+
for (const entry of readdirSync(installDir)) {
|
|
419
|
+
if (/\.ya?ml$/i.test(entry)) {
|
|
420
|
+
return path.join(installDir, entry);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
catch {
|
|
425
|
+
// unreadable
|
|
426
|
+
}
|
|
427
|
+
return null;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Enable a recipe — removes the .disabled marker so triggers can fire.
|
|
431
|
+
* Idempotent: enabling an already-enabled recipe is a no-op.
|
|
432
|
+
*/
|
|
433
|
+
export function runRecipeEnable(name, options = {}) {
|
|
434
|
+
const recipesDir = options.recipesDir ?? INSTALL_RECIPES_DIR;
|
|
435
|
+
const installDir = findInstalledRecipeDir(name, recipesDir);
|
|
436
|
+
if (!installDir) {
|
|
437
|
+
throw new Error(`No installed recipe named "${name}". Run \`patchwork recipe list\` to see installed recipes.`);
|
|
438
|
+
}
|
|
439
|
+
const markerPath = path.join(installDir, DISABLED_MARKER);
|
|
440
|
+
if (!existsSync(markerPath)) {
|
|
441
|
+
return { name, installDir, alreadyEnabled: true };
|
|
442
|
+
}
|
|
443
|
+
unlinkSync(markerPath);
|
|
444
|
+
return { name, installDir, alreadyEnabled: false };
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Disable a recipe — writes the .disabled marker so triggers stop firing.
|
|
448
|
+
* Idempotent: disabling an already-disabled recipe is a no-op.
|
|
449
|
+
*/
|
|
450
|
+
export function runRecipeDisable(name, options = {}) {
|
|
451
|
+
const recipesDir = options.recipesDir ?? INSTALL_RECIPES_DIR;
|
|
452
|
+
const installDir = findInstalledRecipeDir(name, recipesDir);
|
|
453
|
+
if (!installDir) {
|
|
454
|
+
throw new Error(`No installed recipe named "${name}". Run \`patchwork recipe list\` to see installed recipes.`);
|
|
455
|
+
}
|
|
456
|
+
const markerPath = path.join(installDir, DISABLED_MARKER);
|
|
457
|
+
if (existsSync(markerPath)) {
|
|
458
|
+
return { name, installDir, alreadyDisabled: true };
|
|
459
|
+
}
|
|
460
|
+
writeFileSync(markerPath, "");
|
|
461
|
+
return { name, installDir, alreadyDisabled: false };
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Uninstall a recipe — removes its install directory entirely.
|
|
465
|
+
*
|
|
466
|
+
* Returns `{ ok: false, error }` when the recipe isn't found rather than
|
|
467
|
+
* throwing, so the CLI can surface a clean error message instead of a
|
|
468
|
+
* stack trace. Path-traversal attempts in `name` still throw via
|
|
469
|
+
* `findInstalledRecipeDir`'s validator (HIGH-2 hardening from #46).
|
|
470
|
+
*/
|
|
471
|
+
export function runRecipeUninstall(name, options = {}) {
|
|
472
|
+
const recipesDir = options.recipesDir ?? INSTALL_RECIPES_DIR;
|
|
473
|
+
const installDir = findInstalledRecipeDir(name, recipesDir);
|
|
474
|
+
if (!installDir) {
|
|
475
|
+
return {
|
|
476
|
+
ok: false,
|
|
477
|
+
error: `No installed recipe named "${name}". Run \`patchwork recipe list\` to see installed recipes.`,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
rmSync(installDir, { recursive: true, force: true });
|
|
481
|
+
return { ok: true, installDir };
|
|
482
|
+
}
|
|
259
483
|
export function listInstalledRecipes(options = {}) {
|
|
260
484
|
const recipesDir = options.recipesDir ?? INSTALL_RECIPES_DIR;
|
|
261
485
|
if (!existsSync(recipesDir)) {
|
|
@@ -278,6 +502,7 @@ export function listInstalledRecipes(options = {}) {
|
|
|
278
502
|
connectors: manifest.connectors,
|
|
279
503
|
mainRecipe: manifest.recipes.main,
|
|
280
504
|
hasManifest: true,
|
|
505
|
+
enabled: isRecipeEnabled(itemPath),
|
|
281
506
|
});
|
|
282
507
|
}
|
|
283
508
|
else {
|
|
@@ -287,6 +512,7 @@ export function listInstalledRecipes(options = {}) {
|
|
|
287
512
|
name: entryName,
|
|
288
513
|
yamlFiles,
|
|
289
514
|
hasManifest: false,
|
|
515
|
+
enabled: isRecipeEnabled(itemPath),
|
|
290
516
|
});
|
|
291
517
|
}
|
|
292
518
|
else {
|
|
@@ -310,6 +536,7 @@ export function printInstallResult(result) {
|
|
|
310
536
|
if (result.manifest?.connectors && result.manifest.connectors.length > 0) {
|
|
311
537
|
console.log(` Requires connectors: ${result.manifest.connectors.join(", ")}`);
|
|
312
538
|
}
|
|
539
|
+
console.log(` Status: disabled (run \`patchwork recipe enable ${result.name}\` to activate scheduled triggers)`);
|
|
313
540
|
const mainRecipe = result.manifest?.recipes.main ?? result.filesInstalled[0];
|
|
314
541
|
if (mainRecipe) {
|
|
315
542
|
console.log(` Run with: patchwork recipe run ${path.join(result.installDir, mainRecipe)}`);
|
|
@@ -322,17 +549,18 @@ export function printInstalledList(entries) {
|
|
|
322
549
|
}
|
|
323
550
|
const maxName = Math.max(...entries.map((e) => e.name.length), 4);
|
|
324
551
|
const maxVersion = Math.max(...entries.map((e) => (e.version ?? "—").length), 7);
|
|
325
|
-
const header = `${"Name".padEnd(maxName)} ${"Version".padEnd(maxVersion)} Description / Files`;
|
|
552
|
+
const header = `${"Name".padEnd(maxName)} ${"Version".padEnd(maxVersion)} Status Description / Files`;
|
|
326
553
|
console.log(header);
|
|
327
554
|
console.log("-".repeat(Math.min(header.length, 100)));
|
|
328
555
|
for (const entry of entries) {
|
|
329
556
|
const version = (entry.version ?? "—").padEnd(maxVersion);
|
|
557
|
+
const status = (entry.enabled ? "enabled" : "disabled").padEnd(8);
|
|
330
558
|
const detail = entry.hasManifest
|
|
331
559
|
? (entry.description ?? "")
|
|
332
560
|
: `[${(entry.yamlFiles ?? []).join(", ")}]`;
|
|
333
|
-
console.log(`${entry.name.padEnd(maxName)} ${version} ${detail}`);
|
|
561
|
+
console.log(`${entry.name.padEnd(maxName)} ${version} ${status} ${detail}`);
|
|
334
562
|
if (entry.connectors && entry.connectors.length > 0) {
|
|
335
|
-
console.log(`${"".padEnd(maxName)} ${"".padEnd(maxVersion)} connectors: ${entry.connectors.join(", ")}`);
|
|
563
|
+
console.log(`${"".padEnd(maxName)} ${"".padEnd(maxVersion)} ${"".padEnd(8)} connectors: ${entry.connectors.join(", ")}`);
|
|
336
564
|
}
|
|
337
565
|
}
|
|
338
566
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recipeInstall.js","sourceRoot":"","sources":["../../src/commands/recipeInstall.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"recipeInstall.js","sourceRoot":"","sources":["../../src/commands/recipeInstall.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asana connector — read workspaces, projects, tasks, and current user, plus
|
|
3
|
+
* writes (createTask, updateTask, completeTask, addTaskComment).
|
|
4
|
+
*
|
|
5
|
+
* OAuth 2.0 Authorization Code Grant. Asana is a confidential client (bridge
|
|
6
|
+
* holds client secret), so PKCE is not used. Refresh tokens are issued; access
|
|
7
|
+
* tokens expire after 1 hour (3600s).
|
|
8
|
+
*
|
|
9
|
+
* Auth: standard OAuth 2.0 with `client_id` + `client_secret` + `redirect_uri`.
|
|
10
|
+
* - Env vars: ASANA_CLIENT_ID, ASANA_CLIENT_SECRET (mirrors discord/slack)
|
|
11
|
+
* - Stored: getSecretJsonSync("asana") → AsanaTokens
|
|
12
|
+
* - Header: Authorization: Bearer <access_token>
|
|
13
|
+
*
|
|
14
|
+
* Scope note: Asana's only OAuth scope is `default`, which grants read+write
|
|
15
|
+
* combined — there is no read-only-only scope. Defense lives at the recipe-tool
|
|
16
|
+
* layer where each tool declares `isWrite: true|false`. Newer Asana accounts
|
|
17
|
+
* may also expose granular scopes; we set `default` for compatibility.
|
|
18
|
+
*
|
|
19
|
+
* Read tools: getCurrentUser, listWorkspaces, listProjects, listTasks, getTask.
|
|
20
|
+
* Write tools: createTask, updateTask, completeTask, addTaskComment.
|
|
21
|
+
*
|
|
22
|
+
* Idempotency: Asana doesn't honor an Idempotency-Key header. Writes simply
|
|
23
|
+
* throw on error — callers must dedupe via app-level checks if needed.
|
|
24
|
+
*
|
|
25
|
+
* HTTP routes (wired in src/server.ts):
|
|
26
|
+
* GET /connections/asana/auth — redirect to Asana consent
|
|
27
|
+
* GET /connections/asana/callback — exchange code for tokens
|
|
28
|
+
* POST /connections/asana/test — ping Asana API
|
|
29
|
+
* DELETE /connections/asana — clear stored tokens
|
|
30
|
+
*
|
|
31
|
+
* Asana wraps every API response in `{ data: ... }`. We unwrap consistently
|
|
32
|
+
* inside this class so recipe-tool wrappers see clean arrays/objects.
|
|
33
|
+
*
|
|
34
|
+
* Extends BaseConnector for unified auth, retry, rate-limit, error handling.
|
|
35
|
+
* Token refresh is delegated to BaseConnector.refreshToken() via apiCall.
|
|
36
|
+
*/
|
|
37
|
+
import { type AuthContext, BaseConnector, type ConnectorError, type ConnectorStatus, type OAuthConfig } from "./baseConnector.js";
|
|
38
|
+
export interface AsanaTokens {
|
|
39
|
+
access_token: string;
|
|
40
|
+
refresh_token?: string;
|
|
41
|
+
/** ms since epoch; absolute, not relative */
|
|
42
|
+
expires_at?: number;
|
|
43
|
+
scope?: string;
|
|
44
|
+
token_type?: string;
|
|
45
|
+
/** stored at auth time so refresh works even if env vars are absent */
|
|
46
|
+
_client_id?: string;
|
|
47
|
+
_client_secret?: string;
|
|
48
|
+
username?: string;
|
|
49
|
+
user_gid?: string;
|
|
50
|
+
email?: string;
|
|
51
|
+
connected_at: string;
|
|
52
|
+
}
|
|
53
|
+
export interface AsanaUser {
|
|
54
|
+
gid: string;
|
|
55
|
+
name: string;
|
|
56
|
+
email?: string;
|
|
57
|
+
resource_type?: string;
|
|
58
|
+
photo?: {
|
|
59
|
+
image_60x60?: string;
|
|
60
|
+
} | null;
|
|
61
|
+
}
|
|
62
|
+
export interface AsanaWorkspace {
|
|
63
|
+
gid: string;
|
|
64
|
+
name: string;
|
|
65
|
+
resource_type?: string;
|
|
66
|
+
is_organization?: boolean;
|
|
67
|
+
}
|
|
68
|
+
export interface AsanaProject {
|
|
69
|
+
gid: string;
|
|
70
|
+
name: string;
|
|
71
|
+
resource_type?: string;
|
|
72
|
+
archived?: boolean;
|
|
73
|
+
}
|
|
74
|
+
export interface AsanaTask {
|
|
75
|
+
gid: string;
|
|
76
|
+
name: string;
|
|
77
|
+
resource_type?: string;
|
|
78
|
+
completed?: boolean;
|
|
79
|
+
assignee?: {
|
|
80
|
+
gid: string;
|
|
81
|
+
name?: string;
|
|
82
|
+
} | null;
|
|
83
|
+
due_on?: string | null;
|
|
84
|
+
notes?: string;
|
|
85
|
+
}
|
|
86
|
+
export interface AsanaStory {
|
|
87
|
+
gid: string;
|
|
88
|
+
resource_type?: string;
|
|
89
|
+
type?: string;
|
|
90
|
+
text?: string;
|
|
91
|
+
created_at?: string;
|
|
92
|
+
created_by?: {
|
|
93
|
+
gid: string;
|
|
94
|
+
name?: string;
|
|
95
|
+
} | null;
|
|
96
|
+
}
|
|
97
|
+
export interface CreateTaskParams {
|
|
98
|
+
workspaceGid: string;
|
|
99
|
+
name: string;
|
|
100
|
+
projectGid?: string;
|
|
101
|
+
notes?: string;
|
|
102
|
+
assigneeGid?: string;
|
|
103
|
+
/** ISO date YYYY-MM-DD */
|
|
104
|
+
dueOn?: string;
|
|
105
|
+
parentTaskGid?: string;
|
|
106
|
+
}
|
|
107
|
+
export interface UpdateTaskParams {
|
|
108
|
+
name?: string;
|
|
109
|
+
notes?: string;
|
|
110
|
+
completed?: boolean;
|
|
111
|
+
assigneeGid?: string;
|
|
112
|
+
/** ISO date YYYY-MM-DD */
|
|
113
|
+
dueOn?: string;
|
|
114
|
+
}
|
|
115
|
+
export declare function loadTokens(): AsanaTokens | null;
|
|
116
|
+
export declare function saveTokens(tokens: AsanaTokens): void;
|
|
117
|
+
export declare function clearTokens(): void;
|
|
118
|
+
export declare function isConnected(): boolean;
|
|
119
|
+
export declare class AsanaConnector extends BaseConnector {
|
|
120
|
+
readonly providerName = "asana";
|
|
121
|
+
protected getOAuthConfig(): OAuthConfig | null;
|
|
122
|
+
authenticate(): Promise<AuthContext>;
|
|
123
|
+
/**
|
|
124
|
+
* Persist refreshed tokens after BaseConnector.refreshToken() updates
|
|
125
|
+
* `this.auth`. BaseConnector calls `saveTokens()` (its own method on the
|
|
126
|
+
* tokenStorage StoredToken shape); we additionally mirror to our
|
|
127
|
+
* Asana-specific JSON so loadTokens() keeps working for HTTP probes.
|
|
128
|
+
*/
|
|
129
|
+
saveTokens(): Promise<void>;
|
|
130
|
+
healthCheck(): Promise<{
|
|
131
|
+
ok: boolean;
|
|
132
|
+
error?: ConnectorError;
|
|
133
|
+
}>;
|
|
134
|
+
normalizeError(error: unknown): ConnectorError;
|
|
135
|
+
getStatus(): ConnectorStatus;
|
|
136
|
+
getCurrentUser(): Promise<AsanaUser>;
|
|
137
|
+
listWorkspaces(params?: {
|
|
138
|
+
limit?: number;
|
|
139
|
+
}): Promise<AsanaWorkspace[]>;
|
|
140
|
+
listProjects(params: {
|
|
141
|
+
workspaceGid: string;
|
|
142
|
+
limit?: number;
|
|
143
|
+
}): Promise<AsanaProject[]>;
|
|
144
|
+
listTasks(params?: {
|
|
145
|
+
projectGid?: string;
|
|
146
|
+
assignee?: string;
|
|
147
|
+
workspaceGid?: string;
|
|
148
|
+
limit?: number;
|
|
149
|
+
}): Promise<AsanaTask[]>;
|
|
150
|
+
getTask(taskGid: string): Promise<AsanaTask>;
|
|
151
|
+
createTask(params: CreateTaskParams): Promise<AsanaTask>;
|
|
152
|
+
updateTask(taskGid: string, updates: UpdateTaskParams): Promise<AsanaTask>;
|
|
153
|
+
/**
|
|
154
|
+
* Convenience wrapper around updateTask that flips `completed: true`. Lower
|
|
155
|
+
* risk than other updates since it's a single, well-known state transition.
|
|
156
|
+
*/
|
|
157
|
+
completeTask(taskGid: string): Promise<AsanaTask>;
|
|
158
|
+
addTaskComment(taskGid: string, options: {
|
|
159
|
+
text: string;
|
|
160
|
+
}): Promise<AsanaStory>;
|
|
161
|
+
private buildHeaders;
|
|
162
|
+
private captureRateLimit;
|
|
163
|
+
/**
|
|
164
|
+
* Read the response body once and stash the first Asana `errors[].message`
|
|
165
|
+
* onto a sidecar property so normalizeError can include it without a second
|
|
166
|
+
* read. Returns the same Response for `throw` to consume.
|
|
167
|
+
*/
|
|
168
|
+
private attachErrorDetail;
|
|
169
|
+
}
|
|
170
|
+
export declare function getAsanaConnector(): AsanaConnector;
|
|
171
|
+
export { getAsanaConnector as asana };
|
|
172
|
+
export interface ConnectorHandlerResult {
|
|
173
|
+
status: number;
|
|
174
|
+
body: string;
|
|
175
|
+
contentType?: string;
|
|
176
|
+
redirect?: string;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* GET /connections/asana/auth — redirect to Asana consent screen.
|
|
180
|
+
*/
|
|
181
|
+
export declare function handleAsanaAuthorize(): ConnectorHandlerResult;
|
|
182
|
+
/**
|
|
183
|
+
* GET /connections/asana/callback — exchange code for tokens.
|
|
184
|
+
*/
|
|
185
|
+
export declare function handleAsanaCallback(code: string | null, state: string | null, error: string | null): Promise<ConnectorHandlerResult>;
|
|
186
|
+
/**
|
|
187
|
+
* POST /connections/asana/test — verify stored token works.
|
|
188
|
+
*/
|
|
189
|
+
export declare function handleAsanaTest(): Promise<ConnectorHandlerResult>;
|
|
190
|
+
/**
|
|
191
|
+
* DELETE /connections/asana — clear stored tokens.
|
|
192
|
+
*
|
|
193
|
+
* Asana does not expose a public OAuth revocation endpoint, so we just drop
|
|
194
|
+
* local credentials. The token remains valid at Asana until it naturally
|
|
195
|
+
* expires (1h) or the user revokes the integration in their Asana account
|
|
196
|
+
* settings.
|
|
197
|
+
*/
|
|
198
|
+
export declare function handleAsanaDisconnect(): Promise<ConnectorHandlerResult>;
|