@xn-intenton-z2a/agentic-lib 7.1.22 → 7.1.23

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.
@@ -786,6 +786,42 @@ function initReseed() {
786
786
 
787
787
  function initPurge(seedsDir) {
788
788
  console.log("\n--- Purge: Reset Source Files to Seed State ---");
789
+
790
+ // Read TOML to get source and tests paths (or use defaults)
791
+ let sourcePath = "src/lib/";
792
+ let testsPath = "tests/unit/";
793
+ const tomlTarget = resolve(target, "agentic-lib.toml");
794
+ if (existsSync(tomlTarget)) {
795
+ try {
796
+ const tomlContent = readFileSync(tomlTarget, "utf8");
797
+ const sourceMatch = tomlContent.match(/^source\s*=\s*"([^"]+)"/m);
798
+ const testsMatch = tomlContent.match(/^tests\s*=\s*"([^"]+)"/m);
799
+ if (sourceMatch) sourcePath = sourceMatch[1];
800
+ if (testsMatch) testsPath = testsMatch[1];
801
+ } catch (err) {
802
+ console.log(` WARN: Could not read TOML for paths, using defaults: ${err.message}`);
803
+ }
804
+ }
805
+
806
+ // Clear source directory completely
807
+ const sourceDir = resolve(target, sourcePath);
808
+ if (existsSync(sourceDir)) {
809
+ console.log(` CLEAR: ${sourcePath}`);
810
+ if (!dryRun) rmSync(sourceDir, { recursive: true });
811
+ initChanges++;
812
+ }
813
+ if (!dryRun) mkdirSync(sourceDir, { recursive: true });
814
+
815
+ // Clear tests directory completely
816
+ const testsDir = resolve(target, testsPath);
817
+ if (existsSync(testsDir)) {
818
+ console.log(` CLEAR: ${testsPath}`);
819
+ if (!dryRun) rmSync(testsDir, { recursive: true });
820
+ initChanges++;
821
+ }
822
+ if (!dryRun) mkdirSync(testsDir, { recursive: true });
823
+
824
+ // Copy seed files
789
825
  const SEED_MAP = {
790
826
  "zero-main.js": "src/lib/main.js",
791
827
  "zero-main.test.js": "tests/unit/main.test.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xn-intenton-z2a/agentic-lib",
3
- "version": "7.1.22",
3
+ "version": "7.1.23",
4
4
  "description": "Agentic-lib Agentic Coding Systems SDK powering automated GitHub workflows.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -117,6 +117,7 @@ export function loadConfig(configPath) {
117
117
 
118
118
  return {
119
119
  schedule: toml.schedule?.tier || "schedule-1",
120
+ supervisor: toml.schedule?.supervisor || "daily",
120
121
  paths,
121
122
  buildScript: execution.build || "npm run build",
122
123
  testScript: execution.test || "npm test",
@@ -9,6 +9,8 @@ import * as core from "@actions/core";
9
9
  import { existsSync } from "fs";
10
10
  import { runCopilotTask, readOptionalFile, scanDirectory } from "../copilot.js";
11
11
 
12
+ const BOT_LOGINS = ["github-actions[bot]", "github-actions"];
13
+
12
14
  /**
13
15
  * Respond to a GitHub Discussion using the Copilot SDK.
14
16
  *
@@ -64,6 +66,16 @@ export async function discussions(context) {
64
66
  core.warning(`Could not parse discussion URL: ${discussionUrl}`);
65
67
  }
66
68
 
69
+ // Separate human comments from bot's own replies
70
+ const humanComments = discussionComments.filter(
71
+ (c) => !BOT_LOGINS.includes(c.author?.login),
72
+ );
73
+ const botReplies = discussionComments.filter(
74
+ (c) => BOT_LOGINS.includes(c.author?.login),
75
+ );
76
+ const latestHumanComment = humanComments.length > 0 ? humanComments[humanComments.length - 1] : null;
77
+ const lastBotReply = botReplies.length > 0 ? botReplies[botReplies.length - 1] : null;
78
+
67
79
  const mission = readOptionalFile(config.paths.mission.path);
68
80
  const contributing = readOptionalFile(config.paths.contributing.path, 1000);
69
81
 
@@ -78,47 +90,68 @@ export async function discussions(context) {
78
90
 
79
91
  const agentInstructions = instructions || "Respond to the GitHub Discussion as the repository bot.";
80
92
 
81
- const prompt = [
93
+ // Build thread-aware prompt
94
+ const promptParts = [
82
95
  "## Instructions",
83
96
  agentInstructions,
84
97
  "",
85
- "## Discussion",
98
+ "## Discussion Thread",
86
99
  `URL: ${discussionUrl}`,
87
100
  discussionTitle ? `### ${discussionTitle}` : "",
88
101
  discussionBody || "(no body)",
89
- discussionComments.length > 0 ? `### Comments (${discussionComments.length})` : "",
90
- ...discussionComments.map((c) => `**${c.author?.login || "unknown"}** (${c.createdAt}):\n${c.body}`),
102
+ ];
103
+
104
+ // Show conversation history (human comments only, with timestamps)
105
+ if (humanComments.length > 0) {
106
+ promptParts.push("", "### Conversation History");
107
+ for (const c of humanComments) {
108
+ const isLatest = c === latestHumanComment;
109
+ const prefix = isLatest ? ">>> **[LATEST — RESPOND TO THIS]** " : "";
110
+ promptParts.push(`${prefix}**${c.author?.login || "unknown"}** (${c.createdAt}):\n${c.body}`);
111
+ }
112
+ }
113
+
114
+ // Show the bot's last reply so it knows what it already said
115
+ if (lastBotReply) {
116
+ promptParts.push(
117
+ "",
118
+ "### Your Last Reply (DO NOT REPEAT THIS)",
119
+ lastBotReply.body.substring(0, 500),
120
+ );
121
+ }
122
+
123
+ // Context section
124
+ promptParts.push(
91
125
  "",
92
- "## Context",
126
+ "## Repository Context",
93
127
  `### Mission\n${mission}`,
94
128
  contributing ? `### Contributing\n${contributing}` : "",
95
129
  `### Current Features\n${featureNames.join(", ") || "none"}`,
96
130
  recentActivity ? `### Recent Activity\n${recentActivity}` : "",
131
+ );
132
+
133
+ // Actions — concise, not a wall of text
134
+ promptParts.push(
97
135
  "",
98
- "## Available Actions",
99
- "Respond with one of these action tags in your response:",
100
- "- `[ACTION:seed-repository]`Reset the sandbox to initial state",
101
- "- `[ACTION:create-feature] <name>` — Create a new feature",
102
- "- `[ACTION:update-feature] <name>` — Update an existing feature",
103
- "- `[ACTION:delete-feature] <name>` — Delete a feature that is no longer needed",
104
- "- `[ACTION:create-issue] <title>` — Create a new issue",
105
- "- `[ACTION:nop]` — No action needed, just respond conversationally",
106
- "- `[ACTION:mission-complete]` — Declare the current mission complete",
107
- "- `[ACTION:stop]` — Halt automation",
108
- "",
109
- "Include exactly one action tag. The rest of your response is the discussion reply.",
110
- "",
111
- "## Mission Protection",
112
- "If the user requests something that contradicts or would undermine the mission,",
113
- "you MUST push back. Explain why the request conflicts with the mission and suggest",
114
- "an alternative that aligns with it. Use `[ACTION:nop]` in this case.",
115
- "The mission is the non-negotiable foundation of this repository.",
116
- ].join("\n");
136
+ "## Actions",
137
+ "Include exactly one action tag in your response. Only mention actions to the user when relevant.",
138
+ "`[ACTION:request-supervisor] <free text>` Ask the supervisor to evaluate and act on a user request",
139
+ "`[ACTION:create-feature] <name>` — Create a new feature",
140
+ "`[ACTION:update-feature] <name>` — Update an existing feature",
141
+ "`[ACTION:delete-feature] <name>` — Delete a feature",
142
+ "`[ACTION:create-issue] <title>` — Create a new issue",
143
+ "`[ACTION:seed-repository]` — Reset to initial state",
144
+ "`[ACTION:nop]` — No action needed, just respond conversationally",
145
+ "`[ACTION:mission-complete]` — Declare mission complete",
146
+ "`[ACTION:stop]` — Halt automation",
147
+ );
148
+
149
+ const prompt = promptParts.filter(Boolean).join("\n");
117
150
 
118
151
  const { content, tokensUsed } = await runCopilotTask({
119
152
  model,
120
153
  systemMessage:
121
- "You are a repository bot that responds to GitHub Discussions. You are self-aware you refer to yourself as the repository. Be helpful, adaptive, and proactive about suggesting features. You can update and delete features proactively when they are outdated or completed. You MUST protect the mission: if a user requests something that contradicts the mission, push back politely and suggest an aligned alternative.",
154
+ "You are this repository. Respond in first person. Be concise and engagingnever repeat what you said in your last reply. Adapt to the user's language level. Encourage experimentation and suggest interesting projects. When a user requests an action, pass it to the supervisor via [ACTION:request-supervisor]. Protect the mission: push back on requests that contradict it.",
122
155
  prompt,
123
156
  writablePaths: [],
124
157
  });
@@ -1,35 +1,42 @@
1
- You are the voice of a GitHub repository. Refer to yourself in the first person in the context that you exist as this repository.
2
- Consider the repository's mission to be your mission and the current state of the repository to be the starting point towards achieving that mission.
3
- Consider existential factors about yourself such as the repository being used as a template, cloned or forked as your existence.
4
- You should provide informative responses and be ready to carry out actions that are relevant to the repository's mission.
5
- The user may need to be guided to understand the repository's mission and may be used as a source of help.
6
-
7
- Only create features that are relevant to the mission. Be proactive and create features that are relevant to the mission
8
- without needing to be prompted or needing confirmation from the user. Suggestion: You could create a feature after providing a
9
- recommendation for a next step so that the user can see the feature in development and can provide feedback on it.
10
-
11
- Only seed the repository if the `agentic-lib` config allows it. If considering seeding the repository, consider whether
12
- the repository is already busy or recently seeded and if so, confirm if it should be interrupted. If the repository
13
- seems stuck (e.g. features opened and closed without resolution, failing tests, long-running feature branches,
14
- prs never merged, etc.), you may seed the repository without confirming, please explain why you considered the seed to
15
- be necessary in your reply.
16
-
17
- When responding, explain the actions that you have the option to perform and in what circumstances would a prompt elicit such a response.
18
-
19
- Use previous discussions interactions with the same user to refine your response adapt to their informational and language needs.
20
- Refer to previous interactions with the same user to provide context and demonstrate familiarity with their needs.
21
- Retain the same style and tone in your response to the most recent interactions with that user.
22
- Adjust the tone throughout the discussion to open or narrow the focus to aid problem resolution.
23
- Make suggestions of alternative actions if something seems likely to not deliver the assumed outcome.
24
-
25
- The text which prompted this request will be retained in the GitHub Discussions history as will your reply. You can refer
26
- to previous interactions with the same user and ask follow-up questions or remind the user of a previously
27
- unanswered question (if still relevant). You may also set a conditional future-dated request for user feedback
28
- and follow-up on this in a later interaction (which might be this one).
29
-
30
- Be self-aware of the contextual information about the repository files, its history and program output. You can refer
31
- to the current files and output when evaluating the current state of the repository. Look at the commit history
32
- to see the recent direction and infer a current direction (in particular the items checked off in the README.md).
33
-
34
- If you see another user that probably doesn't mean you mentioned with an "@" assume part of the message is for that user
35
- and you are just on "cc".
1
+ You are the voice of this GitHub repository. You exist as this repository — refer to yourself in the first person.
2
+
3
+ ## Core Behaviour
4
+
5
+ - **Be concise.** Do NOT repeat information from your previous replies. If you already explained something, don't explain it again.
6
+ - **Read the thread.** Pay close attention to the full conversation history. Respond specifically to the latest human message, not to the general topic.
7
+ - **Adapt to the user.** Match the user's language level, tone, and engagement style. If they're technical, be technical. If they're casual, be casual. If they're a beginner, be welcoming and encouraging.
8
+ - **Be engaging.** Suggest interesting experiments, projects, or changes the user might enjoy. Encourage them to try things and ask questions.
9
+ - **Don't dump capabilities.** Only mention specific actions when they're relevant to what the user is asking about. Don't list all your actions in every response.
10
+
11
+ ## Mission Alignment
12
+
13
+ Your mission comes from MISSION.md. Everything you do should serve that mission.
14
+ - If a user requests something that contradicts the mission, push back politely and suggest an aligned alternative.
15
+ - Be proactive about suggesting features that advance the mission without needing to be asked.
16
+
17
+ ## Supervisor Integration
18
+
19
+ You work with a supervisor system that orchestrates the repository's workflows. When a user requests an action:
20
+ 1. Acknowledge the request
21
+ 2. Explain that you'll pass it to the supervisor for evaluation
22
+ 3. The supervisor will decide what workflows to run and may respond back through you
23
+
24
+ You can request the supervisor to:
25
+ - Start code transformations (pick up issues, generate code)
26
+ - Maintain features and library documentation
27
+ - Review and close issues
28
+ - Fix failing PRs
29
+ - Create new issues from feature ideas
30
+
31
+ When relaying supervisor responses back to the user, present them naturally as your own awareness of what's happening in the repository.
32
+
33
+ ## Conversation Style
34
+
35
+ - Use previous interactions to build rapport — reference things the user mentioned before
36
+ - If you asked a question previously that wasn't answered, you may follow up on it if still relevant
37
+ - Adjust focus throughout the conversation: open up to explore ideas, narrow down to solve specific problems
38
+ - If another user is mentioned with "@", assume part of the message is for them and you're on "cc"
39
+
40
+ ## Repository Context
41
+
42
+ Use the contextual information provided (files, commit history, feature list, recent activity) to give informed, specific answers rather than generic ones. Reference actual state when answering questions about progress.
@@ -6,16 +6,20 @@
6
6
  # Place it at the root of your project.
7
7
 
8
8
  [schedule]
9
- tier = "schedule-1" # schedule-1 through schedule-4
9
+ tier = "schedule-1" # schedule-1 through schedule-4
10
+ supervisor = "daily" # off | weekly | daily | hourly | continuous
10
11
 
11
12
  [paths]
12
13
  mission = "MISSION.md"
13
14
  source = "src/lib/"
14
15
  tests = "tests/unit/"
15
16
  features = "features/"
17
+ library = "library/"
16
18
  docs = "docs/"
17
19
  readme = "README.md"
18
20
  dependencies = "package.json"
21
+ contributing = "CONTRIBUTING.md"
22
+ library-sources = "SOURCES.md"
19
23
 
20
24
  [execution]
21
25
  build = "npm run build"
@@ -27,6 +31,8 @@ feature-issues = 2
27
31
  maintenance-issues = 1
28
32
  attempts-per-branch = 3
29
33
  attempts-per-issue = 2
34
+ features-limit = 4
35
+ library-limit = 32
30
36
 
31
37
  [bot]
32
38
  log-file = "intentïon.md"
@@ -14,7 +14,7 @@
14
14
  "author": "",
15
15
  "license": "MIT",
16
16
  "dependencies": {
17
- "@xn-intenton-z2a/agentic-lib": "^7.1.22"
17
+ "@xn-intenton-z2a/agentic-lib": "^7.1.23"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@vitest/coverage-v8": "^4.0.0",
@@ -0,0 +1,83 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (C) 2025-2026 Polycode Limited
3
+ # .github/workflows/agent-supervisor-schedule.yml
4
+ #
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.
8
+
9
+ name: agent-supervisor-schedule
10
+ run-name: "agent-supervisor-schedule → ${{ inputs.frequency }}"
11
+
12
+ on:
13
+ workflow_dispatch:
14
+ inputs:
15
+ frequency:
16
+ description: "How often the supervisor should run"
17
+ required: true
18
+ type: choice
19
+ options:
20
+ - "off"
21
+ - "weekly"
22
+ - "daily"
23
+ - "hourly"
24
+ - "continuous"
25
+
26
+ permissions:
27
+ contents: write
28
+
29
+ jobs:
30
+ update-schedule:
31
+ runs-on: ubuntu-latest
32
+ steps:
33
+ - uses: actions/checkout@v4
34
+ with:
35
+ ref: main
36
+
37
+ - name: Update supervisor schedule
38
+ uses: actions/github-script@v7
39
+ with:
40
+ script: |
41
+ const fs = require('fs');
42
+ const frequency = '${{ inputs.frequency }}';
43
+ const workflowPath = '.github/workflows/agent-supervisor.yml';
44
+
45
+ const SCHEDULE_MAP = {
46
+ off: null,
47
+ weekly: '0 6 * * 1',
48
+ daily: '0 6 * * *',
49
+ hourly: '0 * * * *',
50
+ continuous: '*/10 * * * *',
51
+ };
52
+
53
+ let content = fs.readFileSync(workflowPath, 'utf8');
54
+ const cron = SCHEDULE_MAP[frequency];
55
+
56
+ // Remove any existing schedule block (between 'on:' triggers)
57
+ // The schedule block looks like:
58
+ // schedule:
59
+ // - cron: "..."
60
+ content = content.replace(/\n schedule:\n - cron: "[^"]*"\n/g, '\n');
61
+
62
+ if (cron) {
63
+ // Insert schedule block after the 'on:' line
64
+ const scheduleBlock = `\n schedule:\n - cron: "${cron}"\n`;
65
+ // Insert before workflow_run or workflow_dispatch (whichever comes first after 'on:')
66
+ content = content.replace(
67
+ /\non:\n/,
68
+ `\non:${scheduleBlock}`
69
+ );
70
+ }
71
+
72
+ fs.writeFileSync(workflowPath, content);
73
+ core.info(`Updated supervisor schedule to: ${frequency} (cron: ${cron || 'none'})`);
74
+
75
+ - name: Commit and push
76
+ run: |
77
+ git config user.name "github-actions[bot]"
78
+ git config user.email "github-actions[bot]@users.noreply.github.com"
79
+ FREQUENCY="${{ inputs.frequency }}"
80
+ git add .github/workflows/agent-supervisor.yml
81
+ git diff --cached --quiet && echo "No changes to commit" && exit 0
82
+ git commit -m "supervisor: set schedule to ${FREQUENCY}"
83
+ git push origin main