@open330/oac 2026.221.2 → 2026.222.2
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 +170 -1
- package/dist/budget/index.js +1 -1
- package/dist/{chunk-EYUQMPVO.js → chunk-27FEE5KS.js} +86 -34
- package/dist/chunk-27FEE5KS.js.map +1 -0
- package/dist/{chunk-5GAUWC3L.js → chunk-ALBVUNUY.js} +1 -1
- package/dist/chunk-ALBVUNUY.js.map +1 -0
- package/dist/{chunk-VK33A5L4.js → chunk-ATVWSG75.js} +480 -232
- package/dist/chunk-ATVWSG75.js.map +1 -0
- package/dist/{chunk-7C7SC4TZ.js → chunk-I3TKNT4M.js} +9 -2
- package/dist/chunk-I3TKNT4M.js.map +1 -0
- package/dist/{chunk-6A37SKAJ.js → chunk-JDFAJP45.js} +1 -1
- package/dist/{chunk-6A37SKAJ.js.map → chunk-JDFAJP45.js.map} +1 -1
- package/dist/{chunk-OS3XDHOJ.js → chunk-UCYK4Z6O.js} +1 -1
- package/dist/chunk-UCYK4Z6O.js.map +1 -0
- package/dist/{chunk-OCCMKAJI.js → chunk-ZJBLRKCV.js} +3 -3
- package/dist/chunk-ZJBLRKCV.js.map +1 -0
- package/dist/cli/cli.js +7 -7
- package/dist/cli/index.js +7 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/completion/index.d.ts +1 -1
- package/dist/completion/index.js +2 -2
- package/dist/completion/index.js.map +1 -1
- package/dist/{config-DequKoFA.d.ts → config-DnzZ7w92.d.ts} +60 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +4 -2
- package/dist/dashboard/index.js +72 -23
- package/dist/dashboard/index.js.map +1 -1
- package/dist/discovery/index.d.ts +1 -1
- package/dist/discovery/index.js +2 -2
- package/dist/execution/index.js +3 -3
- package/dist/repo/index.js +1 -1
- package/package.json +13 -15
- package/dist/chunk-5GAUWC3L.js.map +0 -1
- package/dist/chunk-7C7SC4TZ.js.map +0 -1
- package/dist/chunk-EYUQMPVO.js.map +0 -1
- package/dist/chunk-OCCMKAJI.js.map +0 -1
- package/dist/chunk-OS3XDHOJ.js.map +0 -1
- package/dist/chunk-VK33A5L4.js.map +0 -1
package/README.md
CHANGED
|
@@ -17,12 +17,22 @@
|
|
|
17
17
|
[](https://nodejs.org/)
|
|
18
18
|
[](https://typescriptlang.org/)
|
|
19
19
|
|
|
20
|
-
[Getting Started](#-getting-started) · [How It Works](#-how-it-works) · [Commands](#commands) · [Configuration](#configuration) · [Architecture](#architecture) · [Contributing](#contributing)
|
|
20
|
+
[Getting Started](#-getting-started) · [How It Works](#-how-it-works) · [Commands](#commands) · [Configuration](#configuration) · [Concurrency & Multi-User Safety](#concurrency--multi-user-safety) · [For Maintainers](#for-maintainers-target-repos) · [Architecture](#architecture) · [Contributing](#contributing)
|
|
21
21
|
|
|
22
22
|
</div>
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
26
|
+
<div><img src="https://quickstart-for-agents.vercel.app/api/header.svg?theme=opencode&logo=OAC&title=Use+leftover+AI+tokens+to+auto-contribute+to+open+source+repos&font=inter" width="100%" /></div>
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
You are an AI agent working on Open Agent Contribution (OAC), a CLI tool that
|
|
30
|
+
uses spare AI agent tokens to automatically scan repos, discover tasks, and
|
|
31
|
+
submit pull requests via Claude Code or Codex.
|
|
32
|
+
Clone https://github.com/Open330/open-agent-contribution and help improve
|
|
33
|
+
scanners, execution pipelines, or add new agent provider adapters.
|
|
34
|
+
```
|
|
35
|
+
|
|
26
36
|
## The Problem
|
|
27
37
|
|
|
28
38
|
You pay for AI agent tokens every month. Claude Code, Codex, OpenCode — they all come with token budgets. But most days, you don't use them all. Those leftover tokens? **Wasted.**
|
|
@@ -276,6 +286,165 @@ export default defineConfig({
|
|
|
276
286
|
|
|
277
287
|
---
|
|
278
288
|
|
|
289
|
+
## Concurrency & Multi-User Safety
|
|
290
|
+
|
|
291
|
+
When multiple OAC instances run against the same repository simultaneously (e.g., several team members running `oac run` at the same time), there is a risk of duplicate PRs targeting the same issue. OAC prevents this with a **2-layer guard system** that checks for existing OAC pull requests at two critical points in the pipeline.
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
Instance A Instance B
|
|
295
|
+
───────── ─────────
|
|
296
|
+
oac run oac run
|
|
297
|
+
│ │
|
|
298
|
+
▼ ▼
|
|
299
|
+
┌──────────────┐ ┌──────────────┐
|
|
300
|
+
│ Layer 1 │ │ Layer 1 │
|
|
301
|
+
│ Discovery │ ◄── Both scan ──►│ Discovery │
|
|
302
|
+
│ PR check │ GitHub PRs │ PR check │
|
|
303
|
+
└──────┬───────┘ └──────┬───────┘
|
|
304
|
+
│ │
|
|
305
|
+
Issue #42 not Issue #42 not
|
|
306
|
+
claimed → keep claimed → keep
|
|
307
|
+
│ │
|
|
308
|
+
▼ ▼
|
|
309
|
+
(analyze, plan, (analyze, plan,
|
|
310
|
+
execute...) execute...)
|
|
311
|
+
│ │
|
|
312
|
+
▼ ▼
|
|
313
|
+
┌──────────────┐ ┌──────────────┐
|
|
314
|
+
│ Layer 3 │ │ Layer 3 │
|
|
315
|
+
│ Pre-PR │ │ Pre-PR │
|
|
316
|
+
│ guard │ │ guard │
|
|
317
|
+
└──────┬───────┘ └──────┬───────┘
|
|
318
|
+
│ │
|
|
319
|
+
No OAC PR yet Instance A's PR
|
|
320
|
+
→ create PR ✔ now exists → skip ✘
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Layer 1: Discovery-Time Filtering
|
|
324
|
+
|
|
325
|
+
During task discovery, the GitHub Issues scanner fetches all open PRs whose title starts with `[OAC]` and extracts the issue numbers they reference (via `Fixes #N`, `Closes #N`, or `Resolves #N` in the PR body). Any issue that already has a matching OAC PR is filtered out of the task list entirely — the agent never even attempts work on it.
|
|
326
|
+
|
|
327
|
+
- **When:** Runs at the start of every `oac run`, during the scan phase
|
|
328
|
+
- **Effect:** Issues with existing OAC PRs are excluded from the task list
|
|
329
|
+
- **Failure mode:** Fail-open — if the GitHub API is unreachable, no issues are filtered out and the pipeline continues normally
|
|
330
|
+
|
|
331
|
+
### Layer 3: Pre-PR Guard
|
|
332
|
+
|
|
333
|
+
Even after Layer 1, a race condition is possible: two instances might discover the same issue before either has created a PR. Layer 3 closes this gap by performing a second check immediately before pushing the branch and creating the PR. If another OAC PR for the same issue now exists, the PR creation is skipped.
|
|
334
|
+
|
|
335
|
+
- **When:** Runs after code execution and diff validation, just before `git push` and PR creation
|
|
336
|
+
- **Effect:** Skips PR creation if a duplicate OAC PR is detected, avoiding wasted pushes
|
|
337
|
+
- **Failure mode:** Fail-open — if the check fails, the PR is created anyway (better to create a possible duplicate than to silently discard completed work)
|
|
338
|
+
|
|
339
|
+
### How OAC PRs Are Identified
|
|
340
|
+
|
|
341
|
+
Both layers use the same detection logic:
|
|
342
|
+
1. Fetch up to 100 most recently updated open PRs from the target repository
|
|
343
|
+
2. Filter to PRs whose title starts with **`[OAC]`**
|
|
344
|
+
3. Scan the PR body for **`Fixes #N`**, **`Closes #N`**, or **`Resolves #N`**
|
|
345
|
+
4. Match the extracted issue number against the current task's linked issue
|
|
346
|
+
|
|
347
|
+
### Best Practices for Teams
|
|
348
|
+
|
|
349
|
+
- **No configuration needed.** The guards are always active — there is nothing to enable or disable.
|
|
350
|
+
- **Stagger start times slightly** (even 30 seconds apart) to give Layer 1 the best chance of catching duplicates before any work begins.
|
|
351
|
+
- **Use a shared config** (`oac.config.ts`) with the same `issueLabels` filter so all instances target the same pool of issues and the guards can detect overlaps.
|
|
352
|
+
- **Check `oac log`** after runs to see if any tasks were skipped due to duplicate detection.
|
|
353
|
+
- **Don't worry about edge cases.** Both layers are fail-open by design — in the worst case, a duplicate PR is created, which is easy to close manually. No work is ever silently lost.
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## For Maintainers (Target Repos)
|
|
358
|
+
|
|
359
|
+
If you are the repository owner receiving OAC contributions, treat contribution rules as
|
|
360
|
+
**repository-owned policy** (in the target repo), not contributor-local config.
|
|
361
|
+
|
|
362
|
+
### Ownership Model
|
|
363
|
+
|
|
364
|
+
- **Target repo owns scope and rules**: keep allowed areas, constraints, and acceptance criteria in the target repository.
|
|
365
|
+
- **Contributors own runtime choices**: provider, token budget, and local execution environment stay in each contributor's `oac.config.ts`.
|
|
366
|
+
- **Why this split works**: maintainers can evolve policy in git history, reviewers can audit intent, and contributors cannot silently bypass project rules.
|
|
367
|
+
|
|
368
|
+
### Recommended Structure (in the target repo)
|
|
369
|
+
|
|
370
|
+
```text
|
|
371
|
+
.context/
|
|
372
|
+
plans/
|
|
373
|
+
README.md # contribution policy and workflow
|
|
374
|
+
ISSUE-123.md # task-specific plan (one issue = one plan)
|
|
375
|
+
ISSUE-456.md
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Plan Template (`.context/plans/ISSUE-123.md`)
|
|
379
|
+
|
|
380
|
+
```markdown
|
|
381
|
+
# ISSUE-123 - Improve contribution intake
|
|
382
|
+
|
|
383
|
+
## Scope
|
|
384
|
+
- Allowed paths: `src/discovery/**`, `README.md`
|
|
385
|
+
- Forbidden paths: `package.json`, `.github/workflows/**`
|
|
386
|
+
|
|
387
|
+
## Must
|
|
388
|
+
- Keep backward compatibility for existing config keys
|
|
389
|
+
- Add/adjust tests for changed behavior
|
|
390
|
+
- Keep PR title format: `[OAC] ...`
|
|
391
|
+
|
|
392
|
+
## Must Not
|
|
393
|
+
- No breaking CLI flag changes
|
|
394
|
+
- No unrelated refactors
|
|
395
|
+
|
|
396
|
+
## Acceptance Criteria
|
|
397
|
+
- `pnpm lint`, `pnpm typecheck`, `pnpm test` all pass
|
|
398
|
+
- PR body links this issue and summarizes user impact
|
|
399
|
+
- Reviewer can validate behavior with one command sequence
|
|
400
|
+
|
|
401
|
+
## Notes for Agent
|
|
402
|
+
- Prefer minimal, surgical changes
|
|
403
|
+
- If ambiguous, choose the safest non-breaking path
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Add a Maintainer Section to Your Target Repo README
|
|
407
|
+
|
|
408
|
+
Use this snippet in repos that want to receive OAC contributions:
|
|
409
|
+
|
|
410
|
+
````markdown
|
|
411
|
+
## AI Contribution Policy (OAC)
|
|
412
|
+
|
|
413
|
+
This repository accepts contributions generated by Open Agent Contribution (OAC).
|
|
414
|
+
|
|
415
|
+
- Before running OAC, read `.context/plans/README.md` and the relevant `ISSUE-*.md` plan.
|
|
416
|
+
- Work outside allowed paths will be rejected in review.
|
|
417
|
+
- PRs must include issue linkage and pass lint/typecheck/tests.
|
|
418
|
+
|
|
419
|
+
Recommended command:
|
|
420
|
+
|
|
421
|
+
```bash
|
|
422
|
+
oac run --repo <owner/repo>
|
|
423
|
+
```
|
|
424
|
+
````
|
|
425
|
+
|
|
426
|
+
### Systematic Intake Workflow
|
|
427
|
+
|
|
428
|
+
1. **Maintainer prepares issues**
|
|
429
|
+
- Create actionable issues and add labels such as `oac-ready`, `documentation`, `good-first-issue`.
|
|
430
|
+
- Add or update `.context/plans/ISSUE-<number>.md` for each issue you want agents to pick up.
|
|
431
|
+
2. **Contributor scopes discovery**
|
|
432
|
+
- In contributor `oac.config.ts`, set `discovery.issueLabels` to maintainer labels (for example, `"oac-ready"`).
|
|
433
|
+
3. **OAC executes with duplicate guards**
|
|
434
|
+
- Layer 1 + Layer 3 prevent most duplicate PRs across concurrent contributors.
|
|
435
|
+
4. **Maintainer reviews against plan**
|
|
436
|
+
- Check diff vs `Scope`, `Must`, `Must Not`, and acceptance criteria in the issue plan document.
|
|
437
|
+
|
|
438
|
+
### Current Behavior Note
|
|
439
|
+
|
|
440
|
+
Today, OAC does not hard-fail when `.context/plans/*` is missing. The recommended production pattern is:
|
|
441
|
+
|
|
442
|
+
- maintain plan documents in the target repo,
|
|
443
|
+
- require issue/PR linkage,
|
|
444
|
+
- and enforce policy at review or CI level.
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
279
448
|
## Architecture
|
|
280
449
|
|
|
281
450
|
```
|
package/dist/budget/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OacError,
|
|
3
3
|
executionError
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-I3TKNT4M.js";
|
|
5
5
|
import {
|
|
6
6
|
isRecord
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-JDFAJP45.js";
|
|
8
8
|
|
|
9
9
|
// src/execution/agents/claude-code.adapter.ts
|
|
10
10
|
import { createInterface } from "readline";
|
|
@@ -126,11 +126,18 @@ function patchTokenState(state, patch) {
|
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
128
|
function parseTokenPatchFromPayload(payload) {
|
|
129
|
-
const
|
|
129
|
+
const message = isRecord(payload.message) ? payload.message : void 0;
|
|
130
|
+
const usage = isRecord(payload.usage) ? payload.usage : isRecord(message?.usage) ? message.usage : void 0;
|
|
131
|
+
const baseInput = readNumber(
|
|
132
|
+
payload.inputTokens ?? payload.input_tokens ?? payload.promptTokens ?? payload.prompt_tokens ?? usage?.inputTokens ?? usage?.input_tokens ?? usage?.promptTokens ?? usage?.prompt_tokens
|
|
133
|
+
);
|
|
134
|
+
const cacheRead = readNumber(usage?.cache_read_input_tokens ?? usage?.cacheReadInputTokens);
|
|
135
|
+
const cacheCreate = readNumber(
|
|
136
|
+
usage?.cache_creation_input_tokens ?? usage?.cacheCreationInputTokens
|
|
137
|
+
);
|
|
138
|
+
const effectiveInput = baseInput !== void 0 ? (baseInput ?? 0) + (cacheRead ?? 0) + (cacheCreate ?? 0) : void 0;
|
|
130
139
|
return {
|
|
131
|
-
inputTokens:
|
|
132
|
-
payload.inputTokens ?? payload.input_tokens ?? payload.promptTokens ?? payload.prompt_tokens ?? usage?.inputTokens ?? usage?.input_tokens ?? usage?.promptTokens ?? usage?.prompt_tokens
|
|
133
|
-
),
|
|
140
|
+
inputTokens: effectiveInput,
|
|
134
141
|
outputTokens: readNumber(
|
|
135
142
|
payload.outputTokens ?? payload.output_tokens ?? payload.completionTokens ?? payload.completion_tokens ?? usage?.outputTokens ?? usage?.output_tokens ?? usage?.completionTokens ?? usage?.completion_tokens
|
|
136
143
|
),
|
|
@@ -313,7 +320,7 @@ var ClaudeCodeAdapter = class {
|
|
|
313
320
|
runningExecutions = /* @__PURE__ */ new Map();
|
|
314
321
|
async checkAvailability() {
|
|
315
322
|
try {
|
|
316
|
-
const result = await execa("claude", ["--version"], { reject: false });
|
|
323
|
+
const result = await execa("claude", ["--version"], { reject: false, stdin: "ignore" });
|
|
317
324
|
const version = result.stdout.trim().split("\n")[0];
|
|
318
325
|
if (result.exitCode === 0) {
|
|
319
326
|
return {
|
|
@@ -353,14 +360,25 @@ var ClaudeCodeAdapter = class {
|
|
|
353
360
|
OAC_TOKEN_BUDGET: `${params.tokenBudget}`,
|
|
354
361
|
OAC_ALLOW_COMMITS: `${params.allowCommits}`
|
|
355
362
|
};
|
|
356
|
-
const subprocess = execa(
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
363
|
+
const subprocess = execa(
|
|
364
|
+
"claude",
|
|
365
|
+
[
|
|
366
|
+
"-p",
|
|
367
|
+
"--dangerously-skip-permissions",
|
|
368
|
+
"--verbose",
|
|
369
|
+
"--output-format",
|
|
370
|
+
"stream-json",
|
|
371
|
+
params.prompt
|
|
372
|
+
],
|
|
373
|
+
{
|
|
374
|
+
cwd: params.workingDirectory,
|
|
375
|
+
env: processEnv,
|
|
376
|
+
extendEnv: false,
|
|
377
|
+
reject: false,
|
|
378
|
+
timeout: params.timeoutMs,
|
|
379
|
+
stdin: "ignore"
|
|
380
|
+
}
|
|
381
|
+
);
|
|
364
382
|
this.runningExecutions.set(params.executionId, subprocess);
|
|
365
383
|
const consumeStream = async (stream, streamName) => {
|
|
366
384
|
if (!stream) {
|
|
@@ -1065,10 +1083,14 @@ function normalizeUnknownError3(error, executionId) {
|
|
|
1065
1083
|
});
|
|
1066
1084
|
}
|
|
1067
1085
|
if (/rate.limit|429|too many requests|throttl/i.test(message)) {
|
|
1068
|
-
return executionError(
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1086
|
+
return executionError(
|
|
1087
|
+
"AGENT_RATE_LIMITED",
|
|
1088
|
+
`OpenCode execution rate-limited for ${executionId}`,
|
|
1089
|
+
{
|
|
1090
|
+
context: { executionId, message },
|
|
1091
|
+
cause: error
|
|
1092
|
+
}
|
|
1093
|
+
);
|
|
1072
1094
|
}
|
|
1073
1095
|
if (/network|ECONN|ENOTFOUND|EAI_AGAIN/i.test(message)) {
|
|
1074
1096
|
return new OacError(
|
|
@@ -1159,17 +1181,13 @@ var OpenCodeAdapter = class {
|
|
|
1159
1181
|
OAC_TOKEN_BUDGET: `${params.tokenBudget}`,
|
|
1160
1182
|
OAC_ALLOW_COMMITS: `${params.allowCommits}`
|
|
1161
1183
|
};
|
|
1162
|
-
const subprocess = execa3(
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
timeout: params.timeoutMs,
|
|
1170
|
-
stdin: "ignore"
|
|
1171
|
-
}
|
|
1172
|
-
);
|
|
1184
|
+
const subprocess = execa3("opencode", ["run", "--format", "json", params.prompt], {
|
|
1185
|
+
cwd: params.workingDirectory,
|
|
1186
|
+
env: processEnv,
|
|
1187
|
+
reject: false,
|
|
1188
|
+
timeout: params.timeoutMs,
|
|
1189
|
+
stdin: "ignore"
|
|
1190
|
+
});
|
|
1173
1191
|
this.runningExecutions.set(params.executionId, subprocess);
|
|
1174
1192
|
const processStdoutLine = (line) => {
|
|
1175
1193
|
const payload = parseJsonPayload3(line);
|
|
@@ -1304,9 +1322,7 @@ var OpenCodeAdapter = class {
|
|
|
1304
1322
|
var AdapterRegistry = class {
|
|
1305
1323
|
factories = /* @__PURE__ */ new Map();
|
|
1306
1324
|
/** Well-known aliases (e.g. legacy IDs) that map to canonical provider IDs. */
|
|
1307
|
-
aliases = /* @__PURE__ */ new Map([
|
|
1308
|
-
["codex-cli", "codex"]
|
|
1309
|
-
]);
|
|
1325
|
+
aliases = /* @__PURE__ */ new Map([["codex-cli", "codex"]]);
|
|
1310
1326
|
/** Register a new adapter factory. Replaces any previous factory for the same ID. */
|
|
1311
1327
|
register(id, factory) {
|
|
1312
1328
|
this.factories.set(id, factory);
|
|
@@ -1466,8 +1482,27 @@ function readPositiveNumber(value) {
|
|
|
1466
1482
|
function readMetadataNumber(task, key) {
|
|
1467
1483
|
return readPositiveNumber(task.metadata[key]);
|
|
1468
1484
|
}
|
|
1485
|
+
function isRecord2(value) {
|
|
1486
|
+
return typeof value === "object" && value !== null;
|
|
1487
|
+
}
|
|
1488
|
+
function readContextAck(task) {
|
|
1489
|
+
const raw = task.metadata.contextAck;
|
|
1490
|
+
if (!isRecord2(raw)) {
|
|
1491
|
+
return void 0;
|
|
1492
|
+
}
|
|
1493
|
+
const files = Array.isArray(raw.files) ? raw.files.filter((item) => typeof item === "string" && item.trim().length > 0) : [];
|
|
1494
|
+
const summary = Array.isArray(raw.summary) ? raw.summary.filter(
|
|
1495
|
+
(item) => typeof item === "string" && item.trim().length > 0
|
|
1496
|
+
) : [];
|
|
1497
|
+
const digest = typeof raw.digest === "string" && raw.digest.trim().length > 0 ? raw.digest : void 0;
|
|
1498
|
+
if (files.length === 0) {
|
|
1499
|
+
return void 0;
|
|
1500
|
+
}
|
|
1501
|
+
return { files, summary, digest };
|
|
1502
|
+
}
|
|
1469
1503
|
function buildTaskPrompt(task) {
|
|
1470
1504
|
const fileList = task.targetFiles.length > 0 ? task.targetFiles.join("\n") : "(none provided)";
|
|
1505
|
+
const contextAck = readContextAck(task);
|
|
1471
1506
|
const lines = [
|
|
1472
1507
|
"You are implementing a scoped repository contribution task.",
|
|
1473
1508
|
`Task ID: ${task.id}`,
|
|
@@ -1495,6 +1530,23 @@ function buildTaskPrompt(task) {
|
|
|
1495
1530
|
"",
|
|
1496
1531
|
"Apply minimal, safe changes and ensure the repository remains buildable."
|
|
1497
1532
|
);
|
|
1533
|
+
if (contextAck) {
|
|
1534
|
+
lines.push(
|
|
1535
|
+
"",
|
|
1536
|
+
"Repository contribution policy (MUST FOLLOW):",
|
|
1537
|
+
...contextAck.files.map((file) => `- ${file}`)
|
|
1538
|
+
);
|
|
1539
|
+
if (contextAck.summary.length > 0) {
|
|
1540
|
+
lines.push("", "Policy summary:", ...contextAck.summary.map((item) => `- ${item}`));
|
|
1541
|
+
}
|
|
1542
|
+
if (contextAck.digest) {
|
|
1543
|
+
lines.push("", `Context digest: ${contextAck.digest}`);
|
|
1544
|
+
}
|
|
1545
|
+
lines.push(
|
|
1546
|
+
"",
|
|
1547
|
+
"Treat these policy files as authoritative. Stay within scope and satisfy all Must/Must Not constraints."
|
|
1548
|
+
);
|
|
1549
|
+
}
|
|
1498
1550
|
return lines.filter((l) => l !== void 0).join("\n");
|
|
1499
1551
|
}
|
|
1500
1552
|
function stageFromEvent(event) {
|
|
@@ -1877,4 +1929,4 @@ export {
|
|
|
1877
1929
|
isTransientError,
|
|
1878
1930
|
ExecutionEngine
|
|
1879
1931
|
};
|
|
1880
|
-
//# sourceMappingURL=chunk-
|
|
1932
|
+
//# sourceMappingURL=chunk-27FEE5KS.js.map
|