Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion actions/setup/js/comment_memory.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
/// <reference types="@actions/github-script" />
require("./shim.cjs");

const path = require("path");
const { sanitizeContent } = require("./sanitize_content.cjs");
const { getErrorMessage } = require("./error_helpers.cjs");
const { SAFE_OUTPUT_E001 } = require("./error_codes.cjs");
const { resolveTarget, isStagedMode } = require("./safe_output_helpers.cjs");
const { resolveTargetRepoConfig, resolveAndValidateRepo } = require("./repo_helpers.cjs");
const { createAuthenticatedGitHubClient } = require("./handler_auth.cjs");
const { renderTemplateFromFile } = require("./messages_core.cjs");
const { generateFooterWithMessages, generateXMLMarker } = require("./messages_footer.cjs");
const { buildWorkflowRunUrl } = require("./workflow_metadata_helpers.cjs");
const { getTrackerID } = require("./get_tracker_id.cjs");
Expand All @@ -18,6 +20,7 @@ const { COMMENT_MEMORY_TAG, COMMENT_MEMORY_MAX_SCAN_PAGES } = require("./comment
// that happen to contain a matching comment-memory tag.
const MANAGED_COMMENT_PROVENANCE_MARKER = "<!-- gh-aw-agentic-workflow:";
const MANAGED_COMMENT_HEADER = "### Comment Memory";
const MANAGED_COMMENT_DISCLOSURE_NOTE_PATH = path.join(__dirname, "../md/comment_memory_disclosure_note.md");

function sanitizeMemoryID(memoryID) {
const normalized = String(memoryID || "default").trim();
Expand All @@ -29,7 +32,7 @@ function sanitizeMemoryID(memoryID) {
}

function buildManagedMemoryBody(rawBody, memoryID, options) {
const { includeFooter, runUrl, workflowName, workflowSource, workflowSourceURL, historyUrl, triggeringIssueNumber, triggeringPRNumber } = options;
const { includeFooter, runUrl, workflowName, workflowSource, workflowSourceURL, historyUrl, triggeringIssueNumber, triggeringPRNumber, disclosureNote } = options;
if (!/^[a-zA-Z0-9_-]+$/.test(memoryID)) {
throw new Error(`${SAFE_OUTPUT_E001}: memory_id must contain only alphanumeric characters, hyphens, and underscores`);
}
Expand All @@ -45,6 +48,12 @@ function buildManagedMemoryBody(rawBody, memoryID, options) {

if (includeFooter) {
core.info(`comment_memory: footer enabled for memory_id='${memoryID}'`);
const resolvedDisclosureNote =
disclosureNote ??
renderTemplateFromFile(MANAGED_COMMENT_DISCLOSURE_NOTE_PATH, {
comment_memory_tag: COMMENT_MEMORY_TAG,
});
body += "\n\n" + resolvedDisclosureNote;
body += "\n\n" + generateFooterWithMessages(workflowName, runUrl, workflowSource, workflowSourceURL, triggeringIssueNumber, triggeringPRNumber, undefined, historyUrl).trimEnd();
} else {
core.info(`comment_memory: footer disabled for memory_id='${memoryID}', adding XML marker only`);
Expand Down Expand Up @@ -109,6 +118,7 @@ async function main(config = {}) {
core.info(`comment_memory: initialized with max=${maxCount}, defaultMemoryID='${defaultMemoryID}', target='${target}', footer=${includeFooter}, staged=${staged}`);

let processedCount = 0;
let cachedDisclosureNote = null;

return async message => {
if (!message || message.type !== "comment_memory") {
Expand Down Expand Up @@ -165,6 +175,12 @@ async function main(config = {}) {
serverUrl: context.serverUrl,
}) || undefined;

if (cachedDisclosureNote === null) {
cachedDisclosureNote = renderTemplateFromFile(MANAGED_COMMENT_DISCLOSURE_NOTE_PATH, {
comment_memory_tag: COMMENT_MEMORY_TAG,
});
}

const managedBody = buildManagedMemoryBody(message.body || "", memoryID, {
includeFooter,
runUrl,
Expand All @@ -174,6 +190,7 @@ async function main(config = {}) {
historyUrl,
triggeringIssueNumber,
triggeringPRNumber,
disclosureNote: cachedDisclosureNote,
});
try {
enforceCommentLimits(managedBody);
Expand Down
7 changes: 7 additions & 0 deletions actions/setup/js/comment_memory.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,14 @@ describe("comment_memory", () => {
expect(body).toContain("### Comment Memory");
expect(body).toContain('<gh-aw-comment-memory id="session">');
expect(body).toContain("Persist me");
expect(body).toContain("> [!NOTE]");
expect(body).toContain("> <summary>What this comment does</summary>");
expect(body).toContain("Generated by");
const memoryEndIdx = body.indexOf("</gh-aw-comment-memory>");
const noteIdx = body.indexOf("> [!NOTE]");
const footerIdx = body.indexOf("Generated by");
expect(memoryEndIdx).toBeLessThan(noteIdx);
expect(noteIdx).toBeLessThan(footerIdx);
});

it("throws E001 for invalid memory ID in managed body builder", async () => {
Expand Down
9 changes: 9 additions & 0 deletions actions/setup/md/comment_memory_disclosure_note.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
> [!NOTE]
> This comment is managed by comment memory.
>
> <details>
> <summary>What this comment does</summary>
>
> It stores persistent context for this thread in the `<{comment_memory_tag}>` block at the top of this comment.
> Edit only the text in that block; workflow metadata and the footer are regenerated automatically.
> </details>
Loading