@ericsanchezok/synergy-github-agenda 0.0.0-stage → 3.1.0

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.
@@ -0,0 +1,53 @@
1
+ import { GitHubProvider } from "@ericsanchezok/synergy-harness/provider/github"
2
+ import { GithubWatchPolicy } from "@ericsanchezok/synergy-agenda/agenda/github-watch-policy"
3
+
4
+ /**
5
+ * Creation-time gate for agenda items with GitHub triggers.
6
+ *
7
+ * A GitHub watch without a resolvable credential polls silently forever and
8
+ * never fires — and an `agenda_watch` with `onGithub` is a continuation
9
+ * blocker, so the origin session would wait indefinitely with no feedback.
10
+ * Reject at creation with concrete connection steps instead of persisting an
11
+ * item that can never fire. Token validity is deliberately not checked here
12
+ * (that needs a live API call); an invalid token surfaces through the existing
13
+ * consecutive-failure auto-pause in the poll loop.
14
+ */
15
+ export namespace GithubWatchPreflight {
16
+ export interface Rejection {
17
+ title: string
18
+ output: string
19
+ metadata: Record<string, any>
20
+ }
21
+
22
+ export async function check(toolName: string): Promise<Rejection | undefined> {
23
+ const watch = await GithubWatchPolicy.read()
24
+ if (watch?.enabled === false) {
25
+ return {
26
+ title: `${toolName} rejected`,
27
+ output: [
28
+ `GitHub triggers are disabled (github.watch.enabled=false in config).`,
29
+ ``,
30
+ `Ask the user to enable them in Settings → GitHub → "Allow GitHub agenda triggers", or set github.watch.enabled=true in 115-github.jsonc.`,
31
+ ].join("\n"),
32
+ metadata: { blocked: true, reason: "github_watch_disabled" } as Record<string, any>,
33
+ }
34
+ }
35
+ const resolved = await GitHubProvider.resolveToken()
36
+ if (!resolved?.token) {
37
+ return {
38
+ title: `${toolName} rejected`,
39
+ output: [
40
+ `No connected GitHub credential — this GitHub watch would poll silently forever and never fire.`,
41
+ ``,
42
+ `Connect one first, then retry this exact call:`,
43
+ `1. Ask the user to connect GitHub in Settings → GitHub (device login, import gh auth token, or paste a token).`,
44
+ `2. Or ensure GH_TOKEN / GITHUB_TOKEN is exported in the Synergy server environment.`,
45
+ ``,
46
+ `Do not substitute a timed delay loop that shell-checks GitHub — that is the approximation this connection replaces. If the user declines to connect, tell them GitHub watches need a credential.`,
47
+ ].join("\n"),
48
+ metadata: { blocked: true, reason: "github_credential_missing" } as Record<string, any>,
49
+ }
50
+ }
51
+ return undefined
52
+ }
53
+ }
@@ -0,0 +1,18 @@
1
+ import watchDescription from "./watch-description.txt"
2
+ import scheduleDescription from "./schedule-description.txt"
3
+ import { AgendaGithubSource } from "@ericsanchezok/synergy-agenda/agenda/github-source"
4
+ import { AgendaGithubTrigger } from "./github-trigger"
5
+ import { GithubWatchPreflight } from "./preflight"
6
+ import { GithubWatchPolicy } from "@ericsanchezok/synergy-agenda/agenda/github-watch-policy"
7
+ import { readConfig } from "@ericsanchezok/synergy-github/config-schema"
8
+ export function registerBridge() {
9
+ AgendaGithubSource.registerSource({
10
+ ...AgendaGithubTrigger,
11
+ descriptions: { watch: watchDescription, schedule: scheduleDescription },
12
+ check: GithubWatchPreflight.check,
13
+ })
14
+ GithubWatchPolicy.register(async () => {
15
+ const watch = (await readConfig()).github?.watch
16
+ return { enabled: watch?.enabled !== false, defaultIntervalMs: watch?.defaultIntervalMs }
17
+ })
18
+ }
@@ -0,0 +1,3 @@
1
+ - `{type:"github", resource:"pr"|"issue"|"workflow"|"check", repository:"owner/repo", number?, ref?, interval?, states?}` — fires when the watched GitHub resource changes state, polled on an interval (default 5m). `number` targets one PR/issue or workflow run id; `ref` targets a branch/tag/commit for workflow/check watches; `states` filters transitions (e.g. ["merged"], ["failure"]). Requires a connected GitHub credential — creation is rejected with connection steps when none resolves; do not substitute a generic `every` interval that shell-checks GitHub.
2
+
3
+ For "wait until a GitHub resource reaches a state" requests, the github trigger IS the right schedule — prefer it over a generic `every` interval plus manual shell checks.
@@ -0,0 +1,5 @@
1
+ Pass exactly one of `delay`, `onSessionEnd`, or `onGithub`.
2
+
3
+ **Prefer managed GitHub watches over repeated shell polling.** When the condition you are waiting for is a GitHub event (PR merged/closed, issue closed, workflow or check run finishing), pass `onGithub: {resource, repository, number?, ref?, states?}` instead of a `delay` plus repeated shell checks. The trigger polls the GitHub REST API with the connected credential on an interval (default 5 minutes, minimum 30 seconds) and wakes you when it next observes a matching state. Intermediate transitions between polls may be missed. `resource` is "pr" | "issue" | "workflow" | "check"; `repository` is owner/repo; `number` targets one PR/issue or workflow run id (omit for the repository's recent ites); `ref` targets a branch/tag/commit for workflow/check watches; `states` filters which new state should wake you (e.g. ["merged"], ["failure"], ["completed"]). Requires a connected GitHub credential — without one the watch is rejected with connection steps; ask the user to connect GitHub in Settings → GitHub rather than substituting timed shell polling.
4
+
5
+ Repo-wide watches (no `number`) fire for transitions of the 10 most recently updated items. A states-filtered watch reports new items first observed already in a targeted state; an unfiltered watch baselines first observations silently, so an item created and merged entirely between two polls is not reported. Point watches (`number`) always see transitions.
package/src/worker.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { version } from "../package.json" with { type: "json" }
2
+ import { githubAgenda } from "./component"
3
+ export const metadata = { id: "github-agenda", version, apiVersion: 1 }
4
+ export function registerWorker() {
5
+ githubAgenda().register()
6
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.