delimit-cli 4.1.53 → 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.
- package/CHANGELOG.md +26 -0
- package/bin/delimit-cli.js +1 -2
- package/bin/delimit-setup.js +22 -7
- package/gateway/ai/agent_dispatch.py +79 -0
- package/gateway/ai/daily_digest.py +386 -0
- package/gateway/ai/ledger_manager.py +32 -0
- package/gateway/ai/license_core.py +2 -0
- package/gateway/ai/notify.py +17 -11
- package/gateway/ai/reddit_proxy.py +28 -9
- package/gateway/ai/sensing/__init__.py +35 -0
- package/gateway/ai/sensing/schema.py +107 -0
- package/gateway/ai/sensing/signal_store.py +348 -0
- package/gateway/ai/server.py +419 -6
- package/gateway/ai/supabase_sync.py +308 -0
- package/gateway/ai/work_order.py +216 -0
- package/gateway/ai/workers/__init__.py +32 -0
- package/gateway/ai/workers/base.py +154 -0
- package/gateway/ai/workers/executor.py +861 -0
- package/gateway/ai/workers/outreach_drafter.py +161 -0
- package/gateway/ai/workers/pr_drafter.py +148 -0
- package/package.json +14 -1
- package/gateway/ai/continuity.py +0 -462
- package/gateway/ai/inbox_daemon_runner.py +0 -217
- package/gateway/ai/loop_engine.py +0 -1303
- package/gateway/ai/social_cache.py +0 -341
- package/gateway/ai/social_daemon.py +0 -483
- package/gateway/ai/tweet_corpus_schema.sql +0 -76
- package/scripts/crosspost_devto.py +0 -304
- package/scripts/demo-v420-clean.sh +0 -267
- package/scripts/demo-v420-deliberation.sh +0 -217
- package/scripts/demo-v420.sh +0 -55
- package/scripts/sync-gateway.sh +0 -112
|
@@ -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.
|
|
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",
|