@xn-intenton-z2a/agentic-lib 7.1.74 → 7.1.76

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.
@@ -213,10 +213,10 @@ jobs:
213
213
 
214
214
  const SCHEDULE_MAP = {
215
215
  off: null,
216
- weekly: '0 6 * * 1',
217
- daily: '0 6 * * *',
218
- hourly: '0 * * * *',
219
- continuous: '*/15 * * * *',
216
+ weekly: '15 6 * * 1',
217
+ daily: '15 6 * * *',
218
+ hourly: '15 * * * *',
219
+ continuous: '5,15,25,35,45,55 * * * *',
220
220
  };
221
221
 
222
222
  if (fs.existsSync(workflowPath)) {
@@ -293,44 +293,10 @@ jobs:
293
293
  outputs:
294
294
  telemetry: ${{ steps.gather.outputs.telemetry }}
295
295
 
296
- # ─── Supervisor: LLM decides what to do ─────────────────────────────
297
- supervisor:
298
- needs: [params, pr-cleanup, telemetry]
299
- if: |
300
- always() &&
301
- (needs.params.outputs.mode == 'full' || needs.params.outputs.mode == 'dev-only') &&
302
- needs.params.result == 'success'
303
- runs-on: ubuntu-latest
304
- steps:
305
- - uses: actions/checkout@v6
306
-
307
- - uses: actions/setup-node@v6
308
- with:
309
- node-version: "24"
310
-
311
- - name: Self-init (agentic-lib dev only)
312
- if: hashFiles('scripts/self-init.sh') != '' && hashFiles('.github/agentic-lib/actions/agentic-step/package.json') == ''
313
- run: bash scripts/self-init.sh
314
-
315
- - name: Install agentic-step dependencies
316
- working-directory: .github/agentic-lib/actions/agentic-step
317
- run: npm ci
318
-
319
- - name: Run supervisor
320
- if: github.repository != 'xn-intenton-z2a/agentic-lib'
321
- uses: ./.github/agentic-lib/actions/agentic-step
322
- env:
323
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
324
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
325
- with:
326
- task: "supervise"
327
- config: ${{ needs.params.outputs.config-path }}
328
- instructions: ".github/agentic-lib/agents/agent-supervisor.md"
329
- model: ${{ needs.params.outputs.model }}
330
-
331
296
  # ─── Maintain: features + library (push to main) ───────────────────
297
+ # Runs early (parallel with pr-cleanup/telemetry) so supervisor sees features.
332
298
  maintain:
333
- needs: [params, supervisor]
299
+ needs: [params]
334
300
  if: |
335
301
  always() &&
336
302
  (needs.params.outputs.mode == 'full' || needs.params.outputs.mode == 'maintain-only') &&
@@ -416,6 +382,41 @@ jobs:
416
382
  commit-message: "agentic-step: maintain features and library"
417
383
  push-ref: ${{ github.ref_name }}
418
384
 
385
+ # ─── Supervisor: LLM decides what to do (after maintain has features) ──
386
+ supervisor:
387
+ needs: [params, pr-cleanup, telemetry, maintain]
388
+ if: |
389
+ always() &&
390
+ (needs.params.outputs.mode == 'full' || needs.params.outputs.mode == 'dev-only') &&
391
+ needs.params.result == 'success'
392
+ runs-on: ubuntu-latest
393
+ steps:
394
+ - uses: actions/checkout@v6
395
+
396
+ - uses: actions/setup-node@v6
397
+ with:
398
+ node-version: "24"
399
+
400
+ - name: Self-init (agentic-lib dev only)
401
+ if: hashFiles('scripts/self-init.sh') != '' && hashFiles('.github/agentic-lib/actions/agentic-step/package.json') == ''
402
+ run: bash scripts/self-init.sh
403
+
404
+ - name: Install agentic-step dependencies
405
+ working-directory: .github/agentic-lib/actions/agentic-step
406
+ run: npm ci
407
+
408
+ - name: Run supervisor
409
+ if: github.repository != 'xn-intenton-z2a/agentic-lib'
410
+ uses: ./.github/agentic-lib/actions/agentic-step
411
+ env:
412
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
413
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
414
+ with:
415
+ task: "supervise"
416
+ config: ${{ needs.params.outputs.config-path }}
417
+ instructions: ".github/agentic-lib/agents/agent-supervisor.md"
418
+ model: ${{ needs.params.outputs.model }}
419
+
419
420
  # ─── Fix stuck PRs with failing checks ─────────────────────────────
420
421
  fix-stuck:
421
422
  needs: [params, supervisor]
@@ -579,7 +580,7 @@ jobs:
579
580
 
580
581
  # ─── Review: close resolved issues, enhance with criteria ──────────
581
582
  review-features:
582
- needs: [params, maintain]
583
+ needs: [params, supervisor]
583
584
  if: |
584
585
  always() &&
585
586
  (needs.params.outputs.mode == 'full' || needs.params.outputs.mode == 'review-only') &&
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xn-intenton-z2a/agentic-lib",
3
- "version": "7.1.74",
3
+ "version": "7.1.76",
4
4
  "description": "Agentic-lib Agentic Coding Systems SDK powering automated GitHub workflows.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -83,19 +83,27 @@ export function generateOutline(raw, filePath) {
83
83
  }
84
84
 
85
85
  /**
86
- * Filter issues by recency and label quality.
86
+ * Filter issues by recency, init epoch, and label quality.
87
87
  *
88
88
  * @param {Array} issues - GitHub issue objects
89
89
  * @param {Object} [options]
90
90
  * @param {number} [options.staleDays=30] - Issues older than this with no activity are excluded
91
91
  * @param {boolean} [options.excludeBotOnly=true] - Exclude issues with only bot labels
92
+ * @param {string} [options.initTimestamp] - ISO timestamp; exclude issues created before this epoch
92
93
  * @returns {Array} Filtered issues
93
94
  */
94
95
  export function filterIssues(issues, options = {}) {
95
- const { staleDays = 30, excludeBotOnly = true } = options;
96
+ const { staleDays = 30, excludeBotOnly = true, initTimestamp } = options;
96
97
  const cutoff = Date.now() - staleDays * 86400000;
98
+ const initEpoch = initTimestamp ? new Date(initTimestamp).getTime() : 0;
97
99
 
98
100
  return issues.filter((issue) => {
101
+ // Exclude issues created before the most recent init
102
+ if (initEpoch > 0) {
103
+ const created = new Date(issue.created_at).getTime();
104
+ if (created < initEpoch) return false;
105
+ }
106
+
99
107
  const lastActivity = new Date(issue.updated_at || issue.created_at).getTime();
100
108
  if (lastActivity < cutoff) return false;
101
109
 
@@ -187,8 +187,10 @@ export async function discussions(context) {
187
187
  const { data: openIssues } = await octokit.rest.issues.listForRepo({
188
188
  ...repo, state: "open", per_page: 10, sort: "created", direction: "asc",
189
189
  });
190
+ const initTimestampForIssues = config?.init?.timestamp || null;
191
+ const initEpochForIssues = initTimestampForIssues ? new Date(initTimestampForIssues).getTime() : 0;
190
192
  repoContext.issuesSummary = openIssues
191
- .filter((i) => !i.pull_request)
193
+ .filter((i) => !i.pull_request && (initEpochForIssues <= 0 || new Date(i.created_at).getTime() >= initEpochForIssues))
192
194
  .map((i) => {
193
195
  const labels = i.labels.map((l) => l.name).join(", ");
194
196
  return `#${i.number}: ${i.title} [${labels || "no labels"}]`;
@@ -238,6 +240,14 @@ export async function discussions(context) {
238
240
  }
239
241
 
240
242
  const discussion = await fetchDiscussion(octokit, discussionUrl, t.discussionComments || 10);
243
+
244
+ // Filter discussion comments to only those after the most recent init
245
+ const initTs = config?.init?.timestamp || null;
246
+ if (initTs && discussion.comments.length > 0) {
247
+ const initDate = new Date(initTs);
248
+ discussion.comments = discussion.comments.filter((c) => new Date(c.createdAt) >= initDate);
249
+ }
250
+
241
251
  const prompt = buildPrompt(discussionUrl, discussion, context, t, repoContext);
242
252
  const { content, tokensUsed, inputTokens, outputTokens, cost } = await runCopilotTask({
243
253
  model,
@@ -45,13 +45,20 @@ export async function maintainFeatures(context) {
45
45
  contentLimit: t.documentSummary || 1000,
46
46
  });
47
47
 
48
- const { data: closedIssues } = await octokit.rest.issues.listForRepo({
48
+ // Filter closed issues to only those created after the most recent init
49
+ const initTimestamp = config.init?.timestamp || null;
50
+ const initEpoch = initTimestamp ? new Date(initTimestamp).getTime() : 0;
51
+
52
+ const { data: closedIssuesRaw } = await octokit.rest.issues.listForRepo({
49
53
  ...repo,
50
54
  state: "closed",
51
55
  per_page: t.issuesScan || 20,
52
56
  sort: "updated",
53
57
  direction: "desc",
54
58
  });
59
+ const closedIssues = initEpoch > 0
60
+ ? closedIssuesRaw.filter((i) => new Date(i.created_at).getTime() >= initEpoch)
61
+ : closedIssuesRaw;
55
62
 
56
63
  const agentInstructions = instructions || "Maintain the feature set by creating, updating, or pruning features.";
57
64
 
@@ -68,7 +75,7 @@ export async function maintainFeatures(context) {
68
75
  libraryDocs.length > 0 ? `## Library Documents (${libraryDocs.length})` : "",
69
76
  ...libraryDocs.map((d) => `### ${d.name}\n${d.content}`),
70
77
  "",
71
- `## Recently Closed Issues (${closedIssues.length})`,
78
+ `## Recently Closed Issues (${closedIssues.length}${initTimestamp ? `, since init ${initTimestamp}` : ""})`,
72
79
  ...closedIssues.slice(0, Math.floor((t.issuesScan || 20) / 2)).map((i) => `- #${i.number}: ${i.title}`),
73
80
  "",
74
81
  "## Your Task",
@@ -51,6 +51,9 @@ async function gatherContext(octokit, repo, config, t) {
51
51
  : [];
52
52
  const libraryLimit = config.paths.library?.limit || 32;
53
53
 
54
+ // Read init timestamp for epoch boundary (used by issue filtering below)
55
+ const initTimestamp = config.init?.timestamp || null;
56
+
54
57
  const { data: openIssues } = await octokit.rest.issues.listForRepo({
55
58
  ...repo,
56
59
  state: "open",
@@ -59,7 +62,7 @@ async function gatherContext(octokit, repo, config, t) {
59
62
  direction: "asc",
60
63
  });
61
64
  const issuesOnly = openIssues.filter((i) => !i.pull_request);
62
- const filteredIssues = filterIssues(issuesOnly, { staleDays: t.staleDays || 30 });
65
+ const filteredIssues = filterIssues(issuesOnly, { staleDays: t.staleDays || 30, initTimestamp });
63
66
  const oldestReadyIssue = filteredIssues.find((i) => i.labels.some((l) => l.name === "ready"));
64
67
  const issuesSummary = filteredIssues.map((i) => {
65
68
  const age = Math.floor((Date.now() - new Date(i.created_at).getTime()) / 86400000);
@@ -77,7 +80,11 @@ async function gatherContext(octokit, repo, config, t) {
77
80
  sort: "updated",
78
81
  direction: "desc",
79
82
  });
80
- for (const ci of closedIssuesRaw.filter((i) => !i.pull_request)) {
83
+ const initEpoch = initTimestamp ? new Date(initTimestamp).getTime() : 0;
84
+ const closedIssuesFiltered = closedIssuesRaw.filter((i) =>
85
+ !i.pull_request && (initEpoch <= 0 || new Date(i.created_at).getTime() >= initEpoch)
86
+ );
87
+ for (const ci of closedIssuesFiltered) {
81
88
  let closeReason = "closed";
82
89
  try {
83
90
  const { data: comments } = await octokit.rest.issues.listComments({
@@ -110,9 +117,6 @@ async function gatherContext(octokit, repo, config, t) {
110
117
  return `#${pr.number}: ${pr.title} (${pr.head.ref}) [${labels || "no labels"}] (${age}d old)`;
111
118
  });
112
119
 
113
- // Read init timestamp for epoch boundary
114
- const initTimestamp = config.init?.timestamp || null;
115
-
116
120
  let workflowsSummary = [];
117
121
  let actionsSinceInit = [];
118
122
  try {
@@ -16,7 +16,7 @@
16
16
  "author": "",
17
17
  "license": "MIT",
18
18
  "dependencies": {
19
- "@xn-intenton-z2a/agentic-lib": "^7.1.74"
19
+ "@xn-intenton-z2a/agentic-lib": "^7.1.76"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@vitest/coverage-v8": "^4.0.18",