@xn-intenton-z2a/agentic-lib 7.1.39 → 7.1.41

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 CHANGED
@@ -157,7 +157,6 @@ Configuration lives in `agentic-lib.toml` at your project root:
157
157
 
158
158
  ```toml
159
159
  [schedule]
160
- tier = "schedule-1" # schedule-1 through schedule-4
161
160
  supervisor = "daily" # off | weekly | daily | hourly | continuous
162
161
 
163
162
  [paths]
@@ -134,7 +134,7 @@ async function runTask(taskName) {
134
134
  const writablePaths = getWritablePathsFromConfig(config);
135
135
  const readOnlyPaths = getReadOnlyPathsFromConfig(config);
136
136
 
137
- console.log(`[config] schedule=${config.schedule}`);
137
+ console.log(`[config] supervisor=${config.supervisor || "daily"}`);
138
138
  console.log(`[config] writable=${writablePaths.join(", ")}`);
139
139
  console.log(`[config] test=${config.testScript}`);
140
140
  console.log("");
@@ -241,7 +241,6 @@ async function loadTaskConfig() {
241
241
  const { parse } = await import("smol-toml");
242
242
  const toml = parse(readFileSync(tomlPath, "utf8"));
243
243
  return {
244
- schedule: toml.schedule?.tier || "schedule-1",
245
244
  missionPath: toml.paths?.mission || "MISSION.md",
246
245
  sourcePath: toml.paths?.source || "src/lib/",
247
246
  testsPath: toml.paths?.tests || "tests/unit/",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xn-intenton-z2a/agentic-lib",
3
- "version": "7.1.39",
3
+ "version": "7.1.41",
4
4
  "description": "Agentic-lib Agentic Coding Systems SDK powering automated GitHub workflows.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -19,6 +19,8 @@ import { parse as parseToml } from "smol-toml";
19
19
  /**
20
20
  * @typedef {Object} AgenticConfig
21
21
  * @property {string} schedule - Schedule identifier
22
+ * @property {string} supervisor - Supervisor frequency (off | weekly | daily | hourly | continuous)
23
+ * @property {string} model - Copilot SDK model for LLM requests
22
24
  * @property {Object<string, PathConfig>} paths - Mapped paths with permissions
23
25
  * @property {string} buildScript - Build command
24
26
  * @property {string} testScript - Test command
@@ -117,8 +119,8 @@ export function loadConfig(configPath) {
117
119
  const bot = toml.bot || {};
118
120
 
119
121
  return {
120
- schedule: toml.schedule?.tier || "schedule-1",
121
122
  supervisor: toml.schedule?.supervisor || "daily",
123
+ model: toml.schedule?.model || "gpt-5-mini",
122
124
  paths,
123
125
  buildScript: execution.build || "npm run build",
124
126
  testScript: execution.test || "npm test",
@@ -5,7 +5,7 @@
5
5
  // Appends structured entries to the intentïon.md activity log,
6
6
  // including commit URLs and safety-check outcomes.
7
7
 
8
- import { writeFileSync, appendFileSync, existsSync, mkdirSync } from "fs";
8
+ import { writeFileSync, readFileSync, appendFileSync, existsSync, mkdirSync } from "fs";
9
9
  import { dirname } from "path";
10
10
  import * as core from "@actions/core";
11
11
 
@@ -73,8 +73,20 @@ export function logActivity({
73
73
 
74
74
  const entry = parts.join("\n");
75
75
 
76
+ const MAX_ENTRIES = 30;
77
+
76
78
  if (existsSync(filepath)) {
77
- appendFileSync(filepath, entry);
79
+ // Rotate: keep only the header + last MAX_ENTRIES entries
80
+ const existing = readFileSync(filepath, "utf8");
81
+ const sections = existing.split("\n## ");
82
+ if (sections.length > MAX_ENTRIES + 1) {
83
+ // sections[0] is the header, sections[1..] are entries (prefixed with "## " after split)
84
+ const header = sections[0];
85
+ const kept = sections.slice(-(MAX_ENTRIES));
86
+ writeFileSync(filepath, header + "\n## " + kept.join("\n## ") + entry);
87
+ } else {
88
+ appendFileSync(filepath, entry);
89
+ }
78
90
  } else {
79
91
  writeFileSync(filepath, `# intentïon Activity Log\n${entry}`);
80
92
  }
@@ -17,21 +17,41 @@ import { runCopilotTask, scanDirectory } from "../copilot.js";
17
17
  export async function reviewIssue(context) {
18
18
  const { octokit, repo, config, issueNumber, instructions, model } = context;
19
19
 
20
- // If no specific issue, review the oldest open automated issue
20
+ // If no specific issue, review the oldest open automated issue that hasn't been recently reviewed
21
21
  let targetIssueNumber = issueNumber;
22
22
  if (!targetIssueNumber) {
23
23
  const { data: openIssues } = await octokit.rest.issues.listForRepo({
24
24
  ...repo,
25
25
  state: "open",
26
26
  labels: "automated",
27
- per_page: 1,
27
+ per_page: 5,
28
28
  sort: "created",
29
29
  direction: "asc",
30
30
  });
31
31
  if (openIssues.length === 0) {
32
32
  return { outcome: "nop", details: "No open automated issues to review" };
33
33
  }
34
- targetIssueNumber = openIssues[0].number;
34
+ // Try each issue, skipping ones that already have a recent automated review comment
35
+ for (const candidate of openIssues) {
36
+ const { data: comments } = await octokit.rest.issues.listComments({
37
+ ...repo,
38
+ issue_number: candidate.number,
39
+ per_page: 5,
40
+ sort: "created",
41
+ direction: "desc",
42
+ });
43
+ const hasRecentReview = comments.some(
44
+ (c) => c.body?.includes("**Automated Review Result:**") && Date.now() - new Date(c.created_at).getTime() < 86400000,
45
+ );
46
+ if (!hasRecentReview) {
47
+ targetIssueNumber = candidate.number;
48
+ break;
49
+ }
50
+ }
51
+ // Fall back to the oldest if all have been recently reviewed
52
+ if (!targetIssueNumber) {
53
+ targetIssueNumber = openIssues[0].number;
54
+ }
35
55
  }
36
56
 
37
57
  const { data: issue } = await octokit.rest.issues.get({
@@ -74,7 +74,6 @@ async function gatherContext(octokit, repo, config) {
74
74
  issuesSummary,
75
75
  prsSummary,
76
76
  workflowsSummary,
77
- schedule: config.schedule,
78
77
  supervisor: config.supervisor,
79
78
  featureIssuesWipLimit: config.featureDevelopmentIssuesWipLimit,
80
79
  maintenanceIssuesWipLimit: config.maintenanceIssuesWipLimit,
@@ -108,7 +107,7 @@ function buildPrompt(ctx, agentInstructions) {
108
107
  `### Recent Activity`,
109
108
  ctx.recentActivity || "none",
110
109
  "",
111
- `### Schedule: ${ctx.schedule}, Supervisor: ${ctx.supervisor}`,
110
+ `### Supervisor: ${ctx.supervisor}`,
112
111
  "",
113
112
  `### Issue Limits`,
114
113
  `Feature development WIP limit: ${ctx.featureIssuesWipLimit}`,
@@ -28,7 +28,15 @@ runs:
28
28
  git add -A
29
29
  if git diff --cached --quiet; then
30
30
  echo "No changes to commit"
31
+ elif git diff --cached --name-only | grep -qvE '(intentïon\.md|intention\.md)$'; then
32
+ # At least one non-log file changed — proceed with commit
33
+ true
31
34
  else
35
+ echo "Only log files changed — skipping commit"
36
+ git reset HEAD -- . > /dev/null 2>&1
37
+ exit 0
38
+ fi
39
+ if ! git diff --cached --quiet; then
32
40
  git commit -m "${{ inputs.commit-message }}"
33
41
  REF="${{ inputs.push-ref }}"
34
42
  MAX_RETRIES=3
@@ -29,7 +29,9 @@ You are the supervisor of an autonomous coding repository. Your job is to advanc
29
29
  - **set-schedule:\<frequency\>** — Change the supervisor schedule. Use `weekly` when mission is substantially achieved, `continuous` to ramp up for active development.
30
30
  - **nop** — When everything is running optimally: transform is active, issues are flowing, no failures.
31
31
 
32
- ## Guidelines
32
+ ## Stale Issue Detection
33
+
34
+ When open issues with the `automated` label lack the `ready` label and are more than 1 day old, and review has run without adding labels, use `github:label-issue` to add the `ready` label directly. Don't wait for review to fix itself — if issues are stuck without `ready` for more than a cycle, label them so transform can pick them up.
33
35
 
34
36
  ## Mission Lifecycle
35
37
 
@@ -1,6 +1,3 @@
1
- # Which agentic-lib workflow schedule should be used?
2
- schedule: schedule-1
3
-
4
1
  # Mapping for from symbolic keys to filepaths for access by agentic-lib workflows with limits and access permissions
5
2
  paths:
6
3
  # Filepaths for elaborator workflows
@@ -4,6 +4,7 @@
4
4
  #
5
5
  # Daily lifecycle: update agentic-lib, run init, test, PR, automerge.
6
6
  # Keeps the repository current with the latest SDK infrastructure.
7
+ # Can also set supervisor schedule and model on init.
7
8
 
8
9
  name: init
9
10
  run-name: "init [${{ github.ref_name }}]"
@@ -32,6 +33,28 @@ on:
32
33
  type: string
33
34
  required: false
34
35
  default: ""
36
+ schedule:
37
+ description: "Supervisor schedule (leave empty to keep current)"
38
+ type: choice
39
+ required: false
40
+ default: ""
41
+ options:
42
+ - ""
43
+ - "off"
44
+ - "weekly"
45
+ - "daily"
46
+ - "hourly"
47
+ - "continuous"
48
+ model:
49
+ description: "Copilot SDK model for LLM requests (leave empty to keep current)"
50
+ type: choice
51
+ required: false
52
+ default: ""
53
+ options:
54
+ - ""
55
+ - gpt-5-mini
56
+ - claude-sonnet-4
57
+ - gpt-4.1
35
58
 
36
59
  permissions: write-all
37
60
 
@@ -49,10 +72,16 @@ jobs:
49
72
  echo "dry-run=${DRY_RUN:-false}" >> $GITHUB_OUTPUT
50
73
  MISSION='${{ inputs.mission }}'
51
74
  echo "mission=${MISSION}" >> $GITHUB_OUTPUT
75
+ SCHEDULE='${{ inputs.schedule }}'
76
+ echo "schedule=${SCHEDULE}" >> $GITHUB_OUTPUT
77
+ MODEL='${{ inputs.model }}'
78
+ echo "model=${MODEL:-gpt-5-mini}" >> $GITHUB_OUTPUT
52
79
  outputs:
53
80
  mode: ${{ steps.normalise.outputs.mode }}
54
81
  dry-run: ${{ steps.normalise.outputs.dry-run }}
55
82
  mission: ${{ steps.normalise.outputs.mission }}
83
+ schedule: ${{ steps.normalise.outputs.schedule }}
84
+ model: ${{ steps.normalise.outputs.model }}
56
85
 
57
86
  init:
58
87
  needs: params
@@ -121,3 +150,13 @@ jobs:
121
150
  --label automerge \
122
151
  --base main \
123
152
  --head "$BRANCH"
153
+
154
+ # Configure schedule after init completes (if schedule parameter provided)
155
+ configure-schedule:
156
+ needs: [params, init]
157
+ if: needs.params.outputs.schedule != ''
158
+ uses: ./.github/workflows/agent-supervisor-schedule.yml
159
+ with:
160
+ frequency: ${{ needs.params.outputs.schedule }}
161
+ model: ${{ needs.params.outputs.model }}
162
+ secrets: inherit
@@ -6,8 +6,8 @@
6
6
  # Place it at the root of your project.
7
7
 
8
8
  [schedule]
9
- tier = "schedule-1" # schedule-1 through schedule-4
10
9
  supervisor = "daily" # off | weekly | daily | hourly | continuous
10
+ model = "gpt-5-mini" # gpt-5-mini | claude-sonnet-4 | gpt-4.1
11
11
 
12
12
  [paths]
13
13
  mission = "MISSION.md"
@@ -14,7 +14,7 @@
14
14
  "author": "",
15
15
  "license": "MIT",
16
16
  "dependencies": {
17
- "@xn-intenton-z2a/agentic-lib": "^7.1.39"
17
+ "@xn-intenton-z2a/agentic-lib": "^7.1.41"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@vitest/coverage-v8": "^4.0.0",
@@ -103,7 +103,7 @@ jobs:
103
103
  ...context.repo,
104
104
  state: 'open',
105
105
  labels: 'automated',
106
- per_page: 1,
106
+ per_page: 20,
107
107
  sort: 'created',
108
108
  direction: 'asc',
109
109
  });
@@ -3,13 +3,25 @@
3
3
  # .github/workflows/agent-supervisor-schedule.yml
4
4
  #
5
5
  # Changes the agent-supervisor's cron schedule by editing the workflow file
6
- # directly and pushing to main. This is the control plane for how often
7
- # the supervisor runs proactively.
6
+ # directly and pushing to main. Also updates the model setting in agentic-lib.toml.
7
+ # This is the control plane for how often the supervisor runs proactively
8
+ # and which LLM model is used.
8
9
 
9
10
  name: agent-supervisor-schedule
10
- run-name: "agent-supervisor-schedule → ${{ inputs.frequency }}"
11
+ run-name: "agent-supervisor-schedule → ${{ inputs.frequency }} (${{ inputs.model }})"
11
12
 
12
13
  on:
14
+ workflow_call:
15
+ inputs:
16
+ frequency:
17
+ description: "How often the supervisor should run"
18
+ required: true
19
+ type: string
20
+ model:
21
+ description: "Copilot SDK model to use"
22
+ required: false
23
+ type: string
24
+ default: "gpt-5-mini"
13
25
  workflow_dispatch:
14
26
  inputs:
15
27
  frequency:
@@ -22,6 +34,15 @@ on:
22
34
  - "daily"
23
35
  - "hourly"
24
36
  - "continuous"
37
+ model:
38
+ description: "Copilot SDK model to use"
39
+ required: false
40
+ type: choice
41
+ default: "gpt-5-mini"
42
+ options:
43
+ - gpt-5-mini
44
+ - claude-sonnet-4
45
+ - gpt-4.1
25
46
 
26
47
  permissions:
27
48
  contents: write
@@ -35,13 +56,15 @@ jobs:
35
56
  ref: main
36
57
  token: ${{ secrets.WORKFLOW_TOKEN }}
37
58
 
38
- - name: Update supervisor schedule
59
+ - name: Update supervisor schedule and model
39
60
  uses: actions/github-script@v7
40
61
  with:
41
62
  script: |
42
63
  const fs = require('fs');
43
64
  const frequency = '${{ inputs.frequency }}';
65
+ const model = '${{ inputs.model || 'gpt-5-mini' }}';
44
66
  const workflowPath = '.github/workflows/agent-supervisor.yml';
67
+ const tomlPath = 'agentic-lib.toml';
45
68
 
46
69
  const SCHEDULE_MAP = {
47
70
  off: null,
@@ -51,6 +74,7 @@ jobs:
51
74
  continuous: '*/15 * * * *',
52
75
  };
53
76
 
77
+ // Update agent-supervisor.yml schedule
54
78
  let content = fs.readFileSync(workflowPath, 'utf8');
55
79
  const cron = SCHEDULE_MAP[frequency];
56
80
 
@@ -73,12 +97,47 @@ jobs:
73
97
  fs.writeFileSync(workflowPath, content);
74
98
  core.info(`Updated supervisor schedule to: ${frequency} (cron: ${cron || 'none'})`);
75
99
 
100
+ // Update agentic-lib.toml with model and supervisor settings
101
+ if (fs.existsSync(tomlPath)) {
102
+ let toml = fs.readFileSync(tomlPath, 'utf8');
103
+
104
+ // Update model setting within [schedule] section
105
+ // Match model line that appears after [schedule] but before any other section
106
+ // Allow optional leading whitespace for robustness
107
+ const scheduleModelRegex = /(\[schedule\][^\[]*?)(^\s*model\s*=\s*"[^"]*")/m;
108
+ if (scheduleModelRegex.test(toml)) {
109
+ // Model exists in schedule section - update it
110
+ toml = toml.replace(scheduleModelRegex, `$1model = "${model}"`);
111
+ } else if (toml.match(/^\[schedule\]/m)) {
112
+ // No model in schedule section - add it after supervisor line (or after section header)
113
+ const supervisorLineRegex = /^(\s*supervisor\s*=\s*"[^"]*")(\s*#.*)?$/m;
114
+ if (supervisorLineRegex.test(toml)) {
115
+ toml = toml.replace(supervisorLineRegex, `$1$2\nmodel = "${model}"`);
116
+ } else {
117
+ // Add after [schedule] header (handle optional trailing content)
118
+ toml = toml.replace(/^(\[schedule\].*)$/m, `$1\nmodel = "${model}"`);
119
+ }
120
+ }
121
+
122
+ // Update supervisor setting within [schedule] section
123
+ const scheduleSupervisorRegex = /(\[schedule\][^\[]*?)(^\s*supervisor\s*=\s*"[^"]*")/m;
124
+ if (scheduleSupervisorRegex.test(toml)) {
125
+ toml = toml.replace(scheduleSupervisorRegex, `$1supervisor = "${frequency}"`);
126
+ }
127
+
128
+ fs.writeFileSync(tomlPath, toml);
129
+ core.info(`Updated agentic-lib.toml: model=${model}, supervisor=${frequency}`);
130
+ } else {
131
+ core.warning('agentic-lib.toml not found — skipping config update');
132
+ }
133
+
76
134
  - name: Commit and push
77
135
  run: |
78
136
  git config user.name "github-actions[bot]"
79
137
  git config user.email "github-actions[bot]@users.noreply.github.com"
80
138
  FREQUENCY="${{ inputs.frequency }}"
81
- git add .github/workflows/agent-supervisor.yml
139
+ MODEL="${{ inputs.model }}"
140
+ git add .github/workflows/agent-supervisor.yml agentic-lib.toml
82
141
  git diff --cached --quiet && echo "No changes to commit" && exit 0
83
- git commit -m "supervisor: set schedule to ${FREQUENCY}"
142
+ git commit -m "supervisor: set schedule to ${FREQUENCY}, model to ${MODEL:-gpt-5-mini}"
84
143
  git push origin main