agentpostmortem 0.1.0
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/INSTALL.md +96 -0
- package/LICENSE +21 -0
- package/README.md +116 -0
- package/dist/chunk-Q7YDLORD.js +547 -0
- package/dist/eval-EOZA44ZZ.js +63 -0
- package/dist/index.d.ts +208 -0
- package/dist/index.js +2964 -0
- package/dist/postmortem.plugin.js +16537 -0
- package/dist/scripts/init.js +119 -0
- package/package.json +70 -0
- package/src/templates/commands/disable-lessons.md +12 -0
- package/src/templates/commands/failures.md +10 -0
- package/src/templates/commands/forget.md +11 -0
- package/src/templates/commands/inspect.md +10 -0
- package/src/templates/commands/postmortem-config.md +11 -0
- package/src/templates/commands/postmortem-eval.md +14 -0
- package/src/templates/commands/record-failure.md +10 -0
- package/src/templates/commands/retry.md +12 -0
- package/src/templates/commands/rules.md +10 -0
- package/src/templates/commands/why-failed.md +10 -0
- package/src/templates/skills/disable-lessons/SKILL.md +34 -0
- package/src/templates/skills/failures/SKILL.md +38 -0
- package/src/templates/skills/inspect/SKILL.md +31 -0
- package/src/templates/skills/postmortem-config/SKILL.md +32 -0
- package/src/templates/skills/postmortem-eval/SKILL.md +29 -0
- package/src/templates/skills/record-failure/SKILL.md +31 -0
- package/src/templates/skills/retry/SKILL.md +34 -0
- package/src/templates/skills/rules/SKILL.md +39 -0
- package/src/templates/skills/why-failed/SKILL.md +32 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// scripts/init.ts
|
|
4
|
+
import fs from "fs/promises";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
async function pathExists(targetPath) {
|
|
8
|
+
try {
|
|
9
|
+
await fs.access(targetPath);
|
|
10
|
+
return true;
|
|
11
|
+
} catch {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function parseArgs(argv) {
|
|
16
|
+
let target = process.cwd();
|
|
17
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
18
|
+
const arg = argv[index];
|
|
19
|
+
if (arg === "--target") {
|
|
20
|
+
const value = argv[index + 1];
|
|
21
|
+
if (!value) {
|
|
22
|
+
throw new Error("missing value for --target");
|
|
23
|
+
}
|
|
24
|
+
target = value;
|
|
25
|
+
index += 1;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
throw new Error(`unknown argument: ${arg}`);
|
|
29
|
+
}
|
|
30
|
+
return { target: path.resolve(target) };
|
|
31
|
+
}
|
|
32
|
+
async function resolveTemplatesDir() {
|
|
33
|
+
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
34
|
+
const candidates = [
|
|
35
|
+
path.resolve(scriptDir, "../../src/templates"),
|
|
36
|
+
path.resolve(scriptDir, "../src/templates")
|
|
37
|
+
];
|
|
38
|
+
for (const candidate of candidates) {
|
|
39
|
+
if (await pathExists(candidate)) {
|
|
40
|
+
return candidate;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
throw new Error(`unable to locate templates directory from ${scriptDir}`);
|
|
44
|
+
}
|
|
45
|
+
async function copyIfMissing(sourcePath, destinationPath, relativePath) {
|
|
46
|
+
await fs.mkdir(path.dirname(destinationPath), { recursive: true });
|
|
47
|
+
if (await pathExists(destinationPath)) {
|
|
48
|
+
console.log(` [skip] ${relativePath} (already exists)`);
|
|
49
|
+
return { copied: 0, skipped: 1 };
|
|
50
|
+
}
|
|
51
|
+
await fs.copyFile(sourcePath, destinationPath);
|
|
52
|
+
console.log(` [copy] ${relativePath}`);
|
|
53
|
+
return { copied: 1, skipped: 0 };
|
|
54
|
+
}
|
|
55
|
+
async function copyCommandTemplates(templatesDir, targetRoot) {
|
|
56
|
+
const commandsTemplateDir = path.join(templatesDir, "commands");
|
|
57
|
+
const commandEntries = await fs.readdir(commandsTemplateDir, { withFileTypes: true });
|
|
58
|
+
let copied = 0;
|
|
59
|
+
let skipped = 0;
|
|
60
|
+
const commandFiles = commandEntries.filter((entry) => entry.isFile() && entry.name.endsWith(".md")).map((entry) => entry.name).sort((left, right) => left.localeCompare(right));
|
|
61
|
+
for (const commandFile of commandFiles) {
|
|
62
|
+
const sourcePath = path.join(commandsTemplateDir, commandFile);
|
|
63
|
+
const relativePath = path.posix.join(".opencode", "commands", commandFile);
|
|
64
|
+
const destinationPath = path.join(targetRoot, ".opencode", "commands", commandFile);
|
|
65
|
+
const result = await copyIfMissing(sourcePath, destinationPath, relativePath);
|
|
66
|
+
copied += result.copied;
|
|
67
|
+
skipped += result.skipped;
|
|
68
|
+
}
|
|
69
|
+
return { copied, skipped };
|
|
70
|
+
}
|
|
71
|
+
async function copySkillTemplates(templatesDir, targetRoot) {
|
|
72
|
+
const skillsTemplateDir = path.join(templatesDir, "skills");
|
|
73
|
+
const skillEntries = await fs.readdir(skillsTemplateDir, { withFileTypes: true });
|
|
74
|
+
let copied = 0;
|
|
75
|
+
let skipped = 0;
|
|
76
|
+
const skillDirectories = skillEntries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => left.localeCompare(right));
|
|
77
|
+
for (const skillName of skillDirectories) {
|
|
78
|
+
const sourcePath = path.join(skillsTemplateDir, skillName, "SKILL.md");
|
|
79
|
+
if (!await pathExists(sourcePath)) {
|
|
80
|
+
throw new Error(`missing skill template: ${sourcePath}`);
|
|
81
|
+
}
|
|
82
|
+
const relativePath = path.posix.join(".opencode", "skills", skillName, "SKILL.md");
|
|
83
|
+
const destinationPath = path.join(targetRoot, ".opencode", "skills", skillName, "SKILL.md");
|
|
84
|
+
const result = await copyIfMissing(sourcePath, destinationPath, relativePath);
|
|
85
|
+
copied += result.copied;
|
|
86
|
+
skipped += result.skipped;
|
|
87
|
+
}
|
|
88
|
+
return { copied, skipped };
|
|
89
|
+
}
|
|
90
|
+
async function ensurePostmortemConfig(targetRoot) {
|
|
91
|
+
const relativePath = path.posix.join(".opencode", "postmortem.json");
|
|
92
|
+
const destinationPath = path.join(targetRoot, relativePath);
|
|
93
|
+
await fs.mkdir(path.dirname(destinationPath), { recursive: true });
|
|
94
|
+
if (await pathExists(destinationPath)) {
|
|
95
|
+
console.log(` [skip] ${relativePath} (already exists)`);
|
|
96
|
+
return { copied: 0, skipped: 1 };
|
|
97
|
+
}
|
|
98
|
+
await fs.writeFile(destinationPath, "{}", "utf8");
|
|
99
|
+
console.log(` [copy] ${relativePath}`);
|
|
100
|
+
return { copied: 1, skipped: 0 };
|
|
101
|
+
}
|
|
102
|
+
async function main() {
|
|
103
|
+
const { target } = parseArgs(process.argv.slice(2));
|
|
104
|
+
const templatesDir = await resolveTemplatesDir();
|
|
105
|
+
console.log(`Initializing templates in ${target}`);
|
|
106
|
+
const commandResult = await copyCommandTemplates(templatesDir, target);
|
|
107
|
+
const skillResult = await copySkillTemplates(templatesDir, target);
|
|
108
|
+
const configResult = await ensurePostmortemConfig(target);
|
|
109
|
+
const copied = commandResult.copied + skillResult.copied + configResult.copied;
|
|
110
|
+
const skipped = commandResult.skipped + skillResult.skipped + configResult.skipped;
|
|
111
|
+
console.log("");
|
|
112
|
+
console.log(`Done. Copied ${copied} file(s), skipped ${skipped} file(s).`);
|
|
113
|
+
console.log("Next step: Add 'agentpostmortem' to your opencode.json plugin array.");
|
|
114
|
+
}
|
|
115
|
+
main().catch((error) => {
|
|
116
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
117
|
+
console.error(`init failed: ${message}`);
|
|
118
|
+
process.exitCode = 1;
|
|
119
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
+
"name": "agentpostmortem",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"private": false,
|
|
6
|
+
"type": "module",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"description": "Postmortem workflow plugin for OpenCode: failure memory, prevention rules, guardrailed retry",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/Tpypan/AgentPostmortem.git"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"opencode",
|
|
15
|
+
"plugin",
|
|
16
|
+
"postmortem",
|
|
17
|
+
"ai",
|
|
18
|
+
"debugging"
|
|
19
|
+
],
|
|
20
|
+
"main": "dist/index.js",
|
|
21
|
+
"types": "dist/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"import": "./dist/index.js",
|
|
25
|
+
"types": "./dist/index.d.ts"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"bin": {
|
|
29
|
+
"postmortem-init": "dist/scripts/init.js"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"src/templates",
|
|
34
|
+
"INSTALL.md",
|
|
35
|
+
"README.md",
|
|
36
|
+
"LICENSE"
|
|
37
|
+
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsup",
|
|
40
|
+
"build:check": "bun run build && bun --eval \"import p from './dist/index.js'; process.exit(typeof p === 'function' ? 0 : 1)\"",
|
|
41
|
+
"test": "bun test",
|
|
42
|
+
"lint": "tsc --noEmit",
|
|
43
|
+
"typecheck": "tsc --noEmit",
|
|
44
|
+
"prepublishOnly": "bun run build"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@opencode-ai/plugin": "^1.2.15",
|
|
48
|
+
"zod": "4.1.8"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^24.3.0",
|
|
52
|
+
"tsup": "^8.0.0",
|
|
53
|
+
"typescript": "^5.9.2"
|
|
54
|
+
},
|
|
55
|
+
"directories": {
|
|
56
|
+
"example": "examples",
|
|
57
|
+
"test": "test"
|
|
58
|
+
},
|
|
59
|
+
"author": "",
|
|
60
|
+
"bugs": {
|
|
61
|
+
"url": "https://github.com/Tpypan/AgentPostmortem/issues"
|
|
62
|
+
},
|
|
63
|
+
"homepage": "https://github.com/Tpypan/AgentPostmortem#readme",
|
|
64
|
+
"engines": {
|
|
65
|
+
"node": ">=16"
|
|
66
|
+
},
|
|
67
|
+
"publishConfig": {
|
|
68
|
+
"access": "public"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Disable or re-enable postmortem lesson injection for the active session
|
|
3
|
+
subtask: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
/disable-lessons
|
|
7
|
+
|
|
8
|
+
Call the `postmortem_disable_lessons` plugin tool with flags mapped from $ARGUMENTS. Examples:
|
|
9
|
+
|
|
10
|
+
tool: postmortem_disable_lessons
|
|
11
|
+
tool: postmortem_disable_lessons --enable
|
|
12
|
+
tool: postmortem_disable_lessons --json
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Manage stored postmortem failures (list/show/forget/delete/prune/purge)
|
|
3
|
+
subtask: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
/failures
|
|
7
|
+
|
|
8
|
+
Call the `postmortem_failures` plugin tool with flags mapped from `$ARGUMENTS`. Example:
|
|
9
|
+
|
|
10
|
+
tool: postmortem_failures --action list --json
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Show or set postmortem storage root selection
|
|
3
|
+
subtask: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
/postmortem-config
|
|
7
|
+
|
|
8
|
+
Call the `postmortem_config` plugin tool with flags mapped from `$ARGUMENTS`. Examples:
|
|
9
|
+
|
|
10
|
+
tool: postmortem_config --action show --json
|
|
11
|
+
tool: postmortem_config --action set --storage repo --json
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Command: postmortem_eval
|
|
2
|
+
|
|
3
|
+
Description:
|
|
4
|
+
Local-only evaluation of repeat-failure metrics from stored failures.jsonl. Reads the project's postmortem store (no telemetry) and computes deterministic metrics.
|
|
5
|
+
|
|
6
|
+
Args:
|
|
7
|
+
--json : output JSON
|
|
8
|
+
--window <n> : lookahead window size (default 10)
|
|
9
|
+
|
|
10
|
+
Metrics:
|
|
11
|
+
totalRecords
|
|
12
|
+
uniqueSignatures
|
|
13
|
+
repeatRateWithinWindow
|
|
14
|
+
repeatCountsBySignature
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Preview or persist a durable postmortem failure record
|
|
3
|
+
subtask: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
/record-failure
|
|
7
|
+
|
|
8
|
+
Call the `postmortem_record_failure` plugin tool with flags mapped from `$ARGUMENTS`. Example:
|
|
9
|
+
|
|
10
|
+
tool: postmortem_record_failure --yes --json
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Preview or emit a guardrailed retry prompt for the last user task
|
|
3
|
+
subtask: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
/retry
|
|
7
|
+
|
|
8
|
+
Call the `postmortem_retry` plugin tool with flags mapped from $ARGUMENTS. Examples:
|
|
9
|
+
|
|
10
|
+
tool: postmortem_retry
|
|
11
|
+
tool: postmortem_retry --skip rule-a --skip rule-b --explain
|
|
12
|
+
tool: postmortem_retry --yes
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Manage stored postmortem guardrail rules (list/show/enable/disable/edit/rate/add_from_failure)
|
|
3
|
+
subtask: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
/rules
|
|
7
|
+
|
|
8
|
+
Call the `postmortem_rules` plugin tool with flags mapped from `$ARGUMENTS`. Example:
|
|
9
|
+
|
|
10
|
+
tool: postmortem_rules --action list --json
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Deterministically analyze a stored failure and generate typed hypotheses + prevention rules
|
|
3
|
+
subtask: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
/why-failed
|
|
7
|
+
|
|
8
|
+
Call the `postmortem_why_failed` plugin tool with flags mapped from `$ARGUMENTS`. Example:
|
|
9
|
+
|
|
10
|
+
tool: postmortem_why_failed --latest --json
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: disable-lessons
|
|
3
|
+
description: Disable or re-enable postmortem guardrail injection for this session.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## What I do
|
|
7
|
+
|
|
8
|
+
- Disable or re-enable postmortem guardrail lessons for the current session
|
|
9
|
+
- Can be toggled on or off as needed
|
|
10
|
+
- Safe for memory by default
|
|
11
|
+
|
|
12
|
+
## How to run
|
|
13
|
+
|
|
14
|
+
Call the tool directly:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
tool: postmortem_disable_lessons
|
|
18
|
+
tool: postmortem_disable_lessons --enable
|
|
19
|
+
tool: postmortem_disable_lessons --disable
|
|
20
|
+
tool: postmortem_disable_lessons --json
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Argument mapping
|
|
24
|
+
|
|
25
|
+
- `disable` (bool): Disable lessons
|
|
26
|
+
- `enable` (bool): Enable lessons
|
|
27
|
+
- `json` (bool): Output as JSON
|
|
28
|
+
|
|
29
|
+
## Safety
|
|
30
|
+
|
|
31
|
+
- All output is redacted by default for memory safety
|
|
32
|
+
- Never request or display secrets
|
|
33
|
+
- To delete all postmortem data, first run `tool: postmortem_config --action show --json` to get the `root` path, then delete it manually with `rm -rf "<root>"`.
|
|
34
|
+
- Repo-local storage is opt-in via `.opencode/postmortem.json`.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: failures
|
|
3
|
+
description: List, show, forget, delete, prune, or purge stored postmortem failures.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## What I do
|
|
7
|
+
|
|
8
|
+
- List all stored postmortem failures
|
|
9
|
+
- Show, forget, delete, prune, or purge failures by ID or session
|
|
10
|
+
- Supports dry run and filtering
|
|
11
|
+
|
|
12
|
+
## How to run
|
|
13
|
+
|
|
14
|
+
Call the tool directly:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
tool: postmortem_failures --action list --json
|
|
18
|
+
tool: postmortem_failures --action delete --id <failureId> --yes --json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Argument mapping
|
|
22
|
+
|
|
23
|
+
- `action` (string): Action to perform (list, show, forget, delete, prune, purge)
|
|
24
|
+
- `id` (string): Failure ID
|
|
25
|
+
- `sessionId` (string): Session ID
|
|
26
|
+
- `json` (bool): Output as JSON
|
|
27
|
+
- `yes` (bool): Confirm destructive actions
|
|
28
|
+
- `dryRun` (bool): Preview changes
|
|
29
|
+
- `maxBytes` (number): Limit output size
|
|
30
|
+
- `olderThanDays` (number): Filter by age
|
|
31
|
+
- `keepLastN` (number): Keep last N failures
|
|
32
|
+
|
|
33
|
+
## Safety
|
|
34
|
+
|
|
35
|
+
- All output is redacted by default for memory safety
|
|
36
|
+
- Never request or display secrets
|
|
37
|
+
- To delete all postmortem data, first run `tool: postmortem_config --action show --json` to get the `root` path, then delete it manually with `rm -rf "<root>"`.
|
|
38
|
+
- Repo-local storage is opt-in via `.opencode/postmortem.json`.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: inspect
|
|
3
|
+
description: Render the last-run postmortem snapshot for this project. Safe by default.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## What I do
|
|
7
|
+
|
|
8
|
+
- Show the most recent postmortem snapshot for the current project
|
|
9
|
+
- Optionally include files, git status, or errors in the output
|
|
10
|
+
- Output is safe for memory by default (redacted)
|
|
11
|
+
|
|
12
|
+
## How to run
|
|
13
|
+
|
|
14
|
+
Call the tool directly:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
tool: postmortem_inspect --json --files --git --errors
|
|
18
|
+
```
|
|
19
|
+
## Argument mapping
|
|
20
|
+
|
|
21
|
+
- `json` (bool): Output as JSON
|
|
22
|
+
- `files` (bool): Include file list
|
|
23
|
+
- `git` (bool): Include git status
|
|
24
|
+
- `errors` (bool): Include error details
|
|
25
|
+
|
|
26
|
+
## Safety
|
|
27
|
+
|
|
28
|
+
- All output is redacted by default for memory safety
|
|
29
|
+
- Never request or display secrets
|
|
30
|
+
- To delete all postmortem data, first run `tool: postmortem_config --action show --json` to get the `root` path, then delete it manually with `rm -rf "<root>"`.
|
|
31
|
+
- Repo-local storage is opt-in via `.opencode/postmortem.json`.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: postmortem-config
|
|
3
|
+
description: Show or set project-local postmortem storage config (user or repo root).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## What I do
|
|
7
|
+
|
|
8
|
+
- Show or set the postmortem storage configuration for this project
|
|
9
|
+
- Switch between user and repo storage, or set raw storage
|
|
10
|
+
- Can output as JSON for scripting
|
|
11
|
+
|
|
12
|
+
## How to run
|
|
13
|
+
|
|
14
|
+
Call the tool directly:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
tool: postmortem_config --action show --json
|
|
18
|
+
tool: postmortem_config --action set --storage repo --json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Argument mapping
|
|
22
|
+
|
|
23
|
+
- `action` (string): Action to perform (show, set)
|
|
24
|
+
- `storage` (string): Storage location (user, repo)
|
|
25
|
+
- `storeRaw` (bool): Store raw data
|
|
26
|
+
- `json` (bool): Output as JSON
|
|
27
|
+
|
|
28
|
+
## Safety
|
|
29
|
+
|
|
30
|
+
- All output is redacted by default for memory safety
|
|
31
|
+
- To delete all postmortem data, first run `tool: postmortem_config --action show --json` to get the `root` path, then delete it manually with `rm -rf "<root>"`.
|
|
32
|
+
- Repo-local storage is opt-in via `.opencode/postmortem.json`.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: postmortem-eval
|
|
3
|
+
description: Local-only evaluation of repeat-failure metrics from stored failures.jsonl.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## What I do
|
|
7
|
+
|
|
8
|
+
- Evaluate repeat-failure metrics from stored failures
|
|
9
|
+
- Operates locally, no remote calls
|
|
10
|
+
- Can limit the evaluation window
|
|
11
|
+
|
|
12
|
+
## How to run
|
|
13
|
+
|
|
14
|
+
Call the tool directly:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
tool: postmortem_eval --json --window 30
|
|
18
|
+
```
|
|
19
|
+
## Argument mapping
|
|
20
|
+
|
|
21
|
+
- `json` (bool): Output as JSON
|
|
22
|
+
- `window` (number): Limit to last N days
|
|
23
|
+
|
|
24
|
+
## Safety
|
|
25
|
+
|
|
26
|
+
- All output is redacted by default for memory safety
|
|
27
|
+
- Never request or display secrets
|
|
28
|
+
- To delete all postmortem data, first run `tool: postmortem_config --action show --json` to get the `root` path, then delete it manually with `rm -rf "<root>"`.
|
|
29
|
+
- Repo-local storage is opt-in via `.opencode/postmortem.json`.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: record-failure
|
|
3
|
+
description: Preview or persist a durable failure record from the last-run snapshot.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## What I do
|
|
7
|
+
|
|
8
|
+
- Record a failure event based on the most recent postmortem snapshot
|
|
9
|
+
- Optionally add a reason or tags
|
|
10
|
+
- Can preview or persist the record
|
|
11
|
+
|
|
12
|
+
## How to run
|
|
13
|
+
|
|
14
|
+
Call the tool directly:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
tool: postmortem_record_failure --yes --json --reason "..." --tags foo --tags bar
|
|
18
|
+
```
|
|
19
|
+
## Argument mapping
|
|
20
|
+
|
|
21
|
+
- `yes` (bool): Persist immediately
|
|
22
|
+
- `json` (bool): Output as JSON
|
|
23
|
+
- `reason` (string): Reason for failure
|
|
24
|
+
- `tags` (string[]): Tags for this failure
|
|
25
|
+
|
|
26
|
+
## Safety
|
|
27
|
+
|
|
28
|
+
- All output is redacted by default for memory safety
|
|
29
|
+
- Never request or display secrets
|
|
30
|
+
- To delete all postmortem data, first run `tool: postmortem_config --action show --json` to get the `root` path, then delete it manually with `rm -rf "<root>"`.
|
|
31
|
+
- Repo-local storage is opt-in via `.opencode/postmortem.json`.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: retry
|
|
3
|
+
description: Preview or emit a guardrailed retry prompt from the latest non-command user task.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## What I do
|
|
7
|
+
|
|
8
|
+
- Preview or emit a retry prompt for the last failed user task
|
|
9
|
+
- Can explain, skip rule IDs, or confirm retry
|
|
10
|
+
- Safe for memory by default
|
|
11
|
+
|
|
12
|
+
## How to run
|
|
13
|
+
|
|
14
|
+
Call the tool directly:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
tool: postmortem_retry
|
|
18
|
+
tool: postmortem_retry --skip rule-a --skip rule-b --explain
|
|
19
|
+
tool: postmortem_retry --yes
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Argument mapping
|
|
23
|
+
|
|
24
|
+
- `yes` (bool): Confirm retry
|
|
25
|
+
- `explain` (bool): Explain the retry
|
|
26
|
+
- `skip` (string[]): Rule IDs to skip
|
|
27
|
+
- `json` (bool): Output as JSON
|
|
28
|
+
|
|
29
|
+
## Safety
|
|
30
|
+
|
|
31
|
+
- All output is redacted by default for memory safety
|
|
32
|
+
- Never request or display secrets
|
|
33
|
+
- To delete all postmortem data, first run `tool: postmortem_config --action show --json` to get the `root` path, then delete it manually with `rm -rf "<root>"`.
|
|
34
|
+
- Repo-local storage is opt-in via `.opencode/postmortem.json`.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rules
|
|
3
|
+
description: List, show, enable, disable, edit, or rate postmortem rules and import suggestions from failure analysis.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## What I do
|
|
7
|
+
|
|
8
|
+
- List, show, enable, disable, edit, or rate postmortem rules
|
|
9
|
+
- Import suggestions from failure analysis
|
|
10
|
+
- Filter, update, or rate rules by ID or failure
|
|
11
|
+
|
|
12
|
+
## How to run
|
|
13
|
+
|
|
14
|
+
Call the tool directly:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
tool: postmortem_rules --action list --json
|
|
18
|
+
tool: postmortem_rules --action disable --id <ruleId> --json
|
|
19
|
+
tool: postmortem_rules --action edit --id <ruleId> --text "..." --json
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Argument mapping
|
|
23
|
+
|
|
24
|
+
- `action` (string): Action to perform (list, show, enable, disable, edit, rate, import)
|
|
25
|
+
- `id` (string): Rule ID
|
|
26
|
+
- `failureId` (string): Filter by failure
|
|
27
|
+
- `json` (bool): Output as JSON
|
|
28
|
+
- `includeDisabled` (bool): Include disabled rules
|
|
29
|
+
- `text` (string): Rule text
|
|
30
|
+
- `severity` (string): Severity level
|
|
31
|
+
- `rating` (string): Rule rating
|
|
32
|
+
- `note` (string): Add a note
|
|
33
|
+
|
|
34
|
+
## Safety
|
|
35
|
+
|
|
36
|
+
- All output is redacted by default for memory safety
|
|
37
|
+
- Never request or display secrets
|
|
38
|
+
- To delete all postmortem data, first run `tool: postmortem_config --action show --json` to get the `root` path, then delete it manually with `rm -rf "<root>"`.
|
|
39
|
+
- Repo-local storage is opt-in via `.opencode/postmortem.json`.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: why-failed
|
|
3
|
+
description: Analyze a stored failure and persist hypotheses and prevention rules.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## What I do
|
|
7
|
+
|
|
8
|
+
- Analyze a stored failure deterministically
|
|
9
|
+
- Persist hypotheses and prevention rules for the failure
|
|
10
|
+
- Can target a specific failure or the latest
|
|
11
|
+
|
|
12
|
+
## How to run
|
|
13
|
+
|
|
14
|
+
Call the tool directly:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
tool: postmortem_why_failed --latest --json
|
|
18
|
+
tool: postmortem_why_failed --id <failureId> --json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Argument mapping
|
|
22
|
+
|
|
23
|
+
- `id` (string): Failure ID to analyze
|
|
24
|
+
- `latest` (bool): Analyze the latest failure
|
|
25
|
+
- `json` (bool): Output as JSON
|
|
26
|
+
|
|
27
|
+
## Safety
|
|
28
|
+
|
|
29
|
+
- All output is redacted by default for memory safety
|
|
30
|
+
- Never request or display secrets
|
|
31
|
+
- To delete all postmortem data, first run `tool: postmortem_config --action show --json` to get the `root` path, then delete it manually with `rm -rf "<root>"`.
|
|
32
|
+
- Repo-local storage is opt-in via `.opencode/postmortem.json`.
|