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
14 changes: 9 additions & 5 deletions packages/cli/src/agent/report.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Topic: report (CLI v%(CLI_VERSION)s / topic v3)
# Topic: report (CLI v%(CLI_VERSION)s / topic v4)

## Goal
Publish a Taskless report: an unlisted page on tskl.es that shows what
Expand Down Expand Up @@ -79,10 +79,14 @@ later and deletes one on request.

4. **Show the result.** On success the CLI prints a short summary: the
rules, what they found in the code today, what review raised over
the window, the link, and when it expires. Show it to the user
exactly as printed. Then tell them, in one line, that the report can
be deleted after they have reviewed it, and that they only need to
ask.
the window, the link, and when it expires. Relay it to the user as
ordinary chat text, NOT inside a code block or quote: a fenced block
makes the link unclickable and buries the report the whole session
led up to. Keep its content and order; do not add, drop, or reword
facts. Put the link on its own line as a plain URL or a Markdown
link, so the user can open it directly, and render the rules as a
list. The summary already says the report can be deleted on
request, so do not repeat it.

If you restate any of the report's numbers in your own words, keep
the kinds apart and label each: counts the CLI found **in the code
Expand Down
21 changes: 20 additions & 1 deletion packages/cli/test/report.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@ describe("taskless report", () => {
it("counts only review comments, and asks for a candidate estimate, not pricing", async () => {
const { stdout, exitCode } = await run(["agent", "report"]);
expect(exitCode).toBe(0);
expect(stdout).toMatch(/^# Topic: report {5}\(CLI v.+ \/ topic v3\)/m);
expect(stdout).toMatch(/^# Topic: report {5}\(CLI v.+ \/ topic v4\)/m);
const flat = stdout.replaceAll(/\s+/g, " ");
const counting = flat.slice(flat.indexOf("## Counting surfaced"));
expect(counting).toContain("**Only review comments count.**");
Expand All @@ -899,6 +899,25 @@ describe("taskless report", () => {
expect(show).toContain("which are **your estimate**");
});

// "Show it exactly as printed" read as verbatim, so agents fenced the
// summary and its link stopped being clickable. The summary already says it
// can be deleted, so the recipe no longer asks for that line again.
it("relays the summary as chat text, not a code block", async () => {
const { stdout, exitCode } = await run(["agent", "report"]);
expect(exitCode).toBe(0);
const flat = stdout.replaceAll(/\s+/g, " ");
const show = flat.slice(
flat.indexOf("**Show the result.**"),
flat.indexOf("**Clean up.**")
);
expect(show).toContain(
"Relay it to the user as ordinary chat text, NOT inside a code block or quote"
);
expect(show).toContain("Put the link on its own line");
expect(show).not.toContain("exactly as printed");
expect(show).toContain("so do not repeat it");
});

it("refuses --from and --delete together", async () => {
const { stderr, exitCode } = await run([
"report",
Expand Down
Loading