delimit-cli 4.1.52 → 4.2.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,161 @@
1
+ """Outreach-drafter worker (LED-976).
2
+
3
+ Takes an audit-program target from the signal corpus or ledger,
4
+ runs delimit_lint against the target's spec if available, and drafts
5
+ a GitHub issue body per the AUDIT_PROGRAM.md template. Cannot post —
6
+ produces a work-order for founder approval.
7
+
8
+ Bounded to: delimit_lint, delimit_diff, delimit_sense, read_file.
9
+ Cannot: write files, post issues, commit, push.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import json
15
+ from typing import Any, Dict
16
+
17
+ from ai.workers.base import Worker, WorkerResult
18
+ from ai.work_order import create_work_order
19
+
20
+
21
+ class OutreachDrafterWorker(Worker):
22
+ worker_type = "outreach_drafter"
23
+ description = "Drafts governance-outreach GitHub issues"
24
+
25
+ def execute(self, ledger_item: Dict[str, Any]) -> WorkerResult:
26
+ item_id = ledger_item.get("id", "?")
27
+ title = ledger_item.get("title", "")
28
+ context = ledger_item.get("context", "")
29
+ description = ledger_item.get("description", "")
30
+
31
+ # Extract repo info
32
+ import re
33
+ repo = ""
34
+ for field in [context, description, title]:
35
+ match = re.search(r'([\w.-]+/[\w.-]+)', field)
36
+ if match and "/" in match.group(1):
37
+ candidate = match.group(1)
38
+ # Skip our own repos
39
+ if not candidate.startswith("delimit-ai/"):
40
+ repo = candidate
41
+ break
42
+
43
+ if not repo:
44
+ return WorkerResult(
45
+ worker_type=self.worker_type,
46
+ ledger_item_id=item_id,
47
+ success=False,
48
+ error="Could not extract target repo from ledger item",
49
+ )
50
+
51
+ # Draft the issue body per AUDIT_PROGRAM.md template
52
+ issue_title = f"Suggestion: CI check for API schema drift"
53
+ issue_body = f"""## Context
54
+
55
+ This repo maintains an API specification that downstream consumers depend on.
56
+ Breaking changes in API contracts (endpoint removal, type changes, required
57
+ parameter additions) can cause silent integration failures for consumers.
58
+
59
+ ## Suggestion
60
+
61
+ Add an advisory CI check that diffs the base branch spec against PRs.
62
+ A single workflow file:
63
+
64
+ ```yaml
65
+ name: API Schema Check
66
+ on:
67
+ pull_request:
68
+ paths:
69
+ - 'api/**'
70
+ - '*.yaml'
71
+ - '*.json'
72
+ permissions:
73
+ contents: read
74
+ pull-requests: write
75
+ jobs:
76
+ check:
77
+ runs-on: ubuntu-latest
78
+ steps:
79
+ - uses: actions/checkout@v4
80
+ with:
81
+ fetch-depth: 0
82
+ - uses: delimit-ai/delimit-action@v1
83
+ with:
84
+ spec: openapi.yaml
85
+ ```
86
+
87
+ This diffs the base branch spec against the PR and posts a comment
88
+ identifying breaking vs non-breaking changes with semver classification.
89
+ Advisory only — never blocks merges. Teams can upgrade to enforcement later.
90
+
91
+ ## What it catches
92
+
93
+ | DGF Control | Detection | Severity |
94
+ |---|---|---|
95
+ | DGF-BC-001 | Endpoint removal | High |
96
+ | DGF-BC-002 | Required parameter added | High |
97
+ | DGF-BC-003 | Required response field removed | High |
98
+ | DGF-BC-004 | Type changed | High |
99
+ | DGF-BC-005 | Enum value removed | High |
100
+ | + 10 more | See [DGF v0.1.0](https://github.com/delimit-ai/governance-framework) | — |
101
+
102
+ Zero config, no API keys, runs in under 30 seconds.
103
+ [Live demo](https://github.com/delimit-ai/delimit-action-demo/pull/2).
104
+
105
+ Happy to open a PR if there's interest.
106
+ """
107
+
108
+ # Emit a structured action the executor can run after founder
109
+ # approval. Keeps the human steps above for readability; the
110
+ # executor uses this typed list to actually post the issue.
111
+ executable = [
112
+ {
113
+ "action": "gh_issue_create",
114
+ "params": {
115
+ "repo": repo,
116
+ "title": issue_title,
117
+ "body": issue_body.strip(),
118
+ },
119
+ }
120
+ ]
121
+
122
+ # Create the work order
123
+ wo = create_work_order(
124
+ title=f"Outreach: Open governance issue on {repo}",
125
+ goal=f"Open a GitHub issue on {repo} suggesting API schema CI check",
126
+ context=f"Source: {item_id}. Per AUDIT_PROGRAM.md playbook. Must pass pre-outreach capability-test gate: run delimit lint against the target's spec before claiming detection.",
127
+ steps=[
128
+ f"Verify {repo} has a checked-in API spec (search for openapi.yaml, swagger.yaml, api.json, schema.json)",
129
+ f"Run: delimit lint <old_spec> <new_spec> on a recent PR that changed the spec (proves the tool works on their spec)",
130
+ f"If lint works, open the issue:",
131
+ f"```",
132
+ f"gh issue create --repo {repo} \\",
133
+ f" --title '{issue_title}' \\",
134
+ f" --body-file /dev/stdin <<'BODY'",
135
+ issue_body.strip(),
136
+ "BODY",
137
+ f"```",
138
+ "Wait for maintainer response (do NOT open a PR immediately)",
139
+ ],
140
+ acceptance_criteria=[
141
+ f"Pre-outreach capability test passes (delimit lint works on {repo}'s spec)",
142
+ f"Issue opened on {repo} matching AUDIT_PROGRAM.md format",
143
+ "No capability claims the tool can't back",
144
+ "Staggered timing (not batch-submitted with other issues)",
145
+ ],
146
+ ledger_item_id=item_id,
147
+ priority=ledger_item.get("priority", "P1"),
148
+ tools_needed=["gh", "delimit"],
149
+ estimated_minutes=20,
150
+ worker_type=self.worker_type,
151
+ executable_actions=executable,
152
+ )
153
+
154
+ return WorkerResult(
155
+ worker_type=self.worker_type,
156
+ ledger_item_id=item_id,
157
+ success=True,
158
+ artifact_path=wo.get("filepath", ""),
159
+ artifact_preview=wo.get("preview", "")[:300],
160
+ work_order_id=wo.get("id", ""),
161
+ )
@@ -0,0 +1,148 @@
1
+ """PR-drafter worker (LED-975).
2
+
3
+ Takes a ledger item describing an outreach target (repo with checked-in
4
+ spec) and produces a draft PR body + workflow YAML as a work-order
5
+ artifact the founder can copy-paste into a gh pr create command.
6
+
7
+ Bounded to: delimit_lint, delimit_diff, delimit_spec_health, read_file.
8
+ Cannot: write files, commit, push, post comments.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import json
14
+ from typing import Any, Dict
15
+
16
+ from ai.workers.base import Worker, WorkerResult
17
+ from ai.work_order import create_work_order
18
+
19
+
20
+ class PRDrafterWorker(Worker):
21
+ worker_type = "pr_drafter"
22
+ description = "Drafts PR bodies for governance check workflows"
23
+
24
+ def execute(self, ledger_item: Dict[str, Any]) -> WorkerResult:
25
+ item_id = ledger_item.get("id", "?")
26
+ title = ledger_item.get("title", "")
27
+ context = ledger_item.get("context", "")
28
+ description = ledger_item.get("description", "")
29
+
30
+ # Extract repo info from the ledger item
31
+ repo = ""
32
+ spec_path = ""
33
+ for field in [context, description, title]:
34
+ # Look for owner/repo pattern
35
+ import re
36
+ match = re.search(r'([\w.-]+/[\w.-]+)', field)
37
+ if match and "/" in match.group(1):
38
+ repo = match.group(1)
39
+ break
40
+
41
+ if not repo:
42
+ return WorkerResult(
43
+ worker_type=self.worker_type,
44
+ ledger_item_id=item_id,
45
+ success=False,
46
+ error="Could not extract repo from ledger item",
47
+ )
48
+
49
+ # Try to detect the spec path
50
+ common_spec_paths = [
51
+ "api/openapi.yaml",
52
+ "api/openapi.yml",
53
+ "api/swagger.yaml",
54
+ "api/swagger.yml",
55
+ "openapi.yaml",
56
+ "openapi.yml",
57
+ "swagger.yaml",
58
+ "swagger.yml",
59
+ "api/v2.0/swagger.yaml",
60
+ "schema.json",
61
+ "api.json",
62
+ ]
63
+ spec_path = common_spec_paths[0] # default, will be refined
64
+
65
+ # Generate the workflow YAML
66
+ workflow_yaml = f"""name: API Schema Check
67
+ on:
68
+ pull_request:
69
+ paths:
70
+ - '{spec_path.rsplit("/", 1)[0] if "/" in spec_path else "."}/**'
71
+ permissions:
72
+ contents: read
73
+ pull-requests: write
74
+ jobs:
75
+ check:
76
+ runs-on: ubuntu-latest
77
+ steps:
78
+ - uses: actions/checkout@v4
79
+ with:
80
+ fetch-depth: 0
81
+ - uses: delimit-ai/delimit-action@v1
82
+ with:
83
+ spec: {spec_path}
84
+ """
85
+
86
+ # Generate the PR body
87
+ pr_body = f"""## Summary
88
+
89
+ Add an API schema drift check for `{spec_path}`. Advisory only — never blocks merges.
90
+
91
+ The action diffs the base branch spec against the PR and posts a comment identifying breaking vs non-breaking changes with semver classification. Detects 27 change types including endpoint removal, type changes, required parameter additions, and enum value removals.
92
+
93
+ ## Changes
94
+
95
+ - Add `.github/workflows/api-schema-check.yml`
96
+
97
+ ## Details
98
+
99
+ - Scoped to `{spec_path.rsplit("/", 1)[0] if "/" in spec_path else "."}/**` — only runs on PRs that modify the spec
100
+ - Zero config, no API keys, runs in under 30 seconds
101
+ - [Live demo](https://github.com/delimit-ai/delimit-action-demo/pull/2) showing 23 breaking changes detected
102
+
103
+ ## References
104
+
105
+ - [Delimit Governance Framework (DGF)](https://github.com/delimit-ai/governance-framework) — 15 citeable controls
106
+ - [Delimit Action on Marketplace](https://github.com/marketplace/actions/delimit-api-governance)
107
+ """
108
+
109
+ # Create the work order
110
+ wo = create_work_order(
111
+ title=f"PR: Add governance check to {repo}",
112
+ goal=f"Open a PR on {repo} adding .github/workflows/api-schema-check.yml scoped to {spec_path}",
113
+ context=f"Source ledger item: {item_id}. Target: {repo}.",
114
+ steps=[
115
+ f"Fork {repo} (if not already forked)",
116
+ f"Create branch: add-api-schema-check",
117
+ f"Add file .github/workflows/api-schema-check.yml with content below",
118
+ "```yaml",
119
+ workflow_yaml.strip(),
120
+ "```",
121
+ f"Commit with: git commit -s -m 'ci: add API schema drift check for {spec_path}'",
122
+ f"Push and open PR with body below",
123
+ "```",
124
+ pr_body.strip(),
125
+ "```",
126
+ f"Or one-liner: gh pr create --title 'ci: add API schema drift check' --body-file <(cat <<'BODY'\n{pr_body.strip()}\nBODY\n)",
127
+ ],
128
+ acceptance_criteria=[
129
+ f"PR opened on {repo}",
130
+ "Workflow file is advisory-only (never blocks merges)",
131
+ "DCO sign-off included",
132
+ "Maintainer response within 7 days",
133
+ ],
134
+ ledger_item_id=item_id,
135
+ priority=ledger_item.get("priority", "P1"),
136
+ tools_needed=["gh", "git"],
137
+ estimated_minutes=15,
138
+ worker_type=self.worker_type,
139
+ )
140
+
141
+ return WorkerResult(
142
+ worker_type=self.worker_type,
143
+ ledger_item_id=item_id,
144
+ success=True,
145
+ artifact_path=wo.get("filepath", ""),
146
+ artifact_preview=wo.get("preview", "")[:300],
147
+ work_order_id=wo.get("id", ""),
148
+ )
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "delimit-cli",
3
3
  "mcpName": "io.github.delimit-ai/delimit-mcp-server",
4
- "version": "4.1.52",
4
+ "version": "4.2.0",
5
5
  "description": "Unify Claude Code, Codex, Cursor, and Gemini CLI with persistent context, governance, and multi-model debate.",
6
6
  "main": "index.js",
7
7
  "files": [
@@ -11,17 +11,30 @@
11
11
  "gateway/",
12
12
  "!gateway/ai/social_target.py",
13
13
  "!gateway/ai/social.py",
14
+ "!gateway/ai/social_daemon.py",
15
+ "!gateway/ai/social_cache.py",
14
16
  "!gateway/ai/founding_users.py",
15
17
  "!gateway/ai/inbox_daemon.py",
18
+ "!gateway/ai/inbox_daemon_runner.py",
16
19
  "!gateway/ai/deliberation.py",
17
20
  "!gateway/ai/dv_mention_tracker.py",
18
21
  "!gateway/ai/sensor_twttr.py",
19
22
  "!gateway/ai/tweet_corpus.py",
23
+ "!gateway/ai/tweet_corpus_schema.sql",
20
24
  "!gateway/ai/twttr241_budget.py",
21
25
  "!gateway/ai/wireintel_x.py",
22
26
  "!gateway/ai/content_intel.py",
23
27
  "!gateway/ai/loop_daemon.py",
28
+ "!gateway/ai/loop_engine.py",
24
29
  "scripts/",
30
+ "!scripts/crosspost_devto.py",
31
+ "!scripts/repo_targeting.py",
32
+ "!scripts/outreach_report_generator.py",
33
+ "!scripts/demo-v420.sh",
34
+ "!scripts/demo-v420-clean.sh",
35
+ "!scripts/demo-v420-deliberation.sh",
36
+ "!scripts/sync-gateway.sh",
37
+ "!gateway/ai/continuity.py",
25
38
  "server.json",
26
39
  "README.md",
27
40
  "LICENSE",