@reqall/claude-plugin 0.0.1
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/dist/hooks/classify.d.ts +2 -0
- package/dist/hooks/classify.d.ts.map +1 -0
- package/dist/hooks/classify.js +29 -0
- package/dist/hooks/classify.js.map +1 -0
- package/dist/hooks/classify.mjs +74 -0
- package/dist/hooks/context.d.ts +2 -0
- package/dist/hooks/context.d.ts.map +1 -0
- package/dist/hooks/context.js +33 -0
- package/dist/hooks/context.js.map +1 -0
- package/dist/hooks/context.mjs +60 -0
- package/dist/hooks/plan.d.ts +2 -0
- package/dist/hooks/plan.d.ts.map +1 -0
- package/dist/hooks/plan.js +33 -0
- package/dist/hooks/plan.js.map +1 -0
- package/dist/hooks/plan.mjs +62 -0
- package/hooks/classify.ts +31 -0
- package/hooks/context.ts +37 -0
- package/hooks/hooks.json +20 -0
- package/hooks/plan.ts +37 -0
- package/mcp-servers.json +9 -0
- package/package.json +21 -0
- package/plugin.json +7 -0
- package/scripts/bundle-hooks.js +25 -0
- package/skills/issues/SKILL.md +47 -0
- package/skills/projects/SKILL.md +39 -0
- package/skills/review-issues/SKILL.md +31 -0
- package/skills/review-specs/SKILL.md +31 -0
- package/skills/specs/SKILL.md +43 -0
- package/tsconfig.json +8 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../hooks/classify.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stop hook — Work Classification (post-task)
|
|
3
|
+
*
|
|
4
|
+
* Reads the agent's session transcript and classifies the work done.
|
|
5
|
+
* Outputs a prompt for the agent to persist the classification via MCP tools.
|
|
6
|
+
*/
|
|
7
|
+
import { loadConfig, detectProject, CLASSIFICATION_PROMPT } from '@reqall/core';
|
|
8
|
+
async function main() {
|
|
9
|
+
try {
|
|
10
|
+
const config = loadConfig();
|
|
11
|
+
const projectName = config.projectName || detectProject();
|
|
12
|
+
// Read transcript from stdin
|
|
13
|
+
const input = await new Promise((resolve) => {
|
|
14
|
+
let data = '';
|
|
15
|
+
process.stdin.on('data', (chunk) => { data += chunk; });
|
|
16
|
+
process.stdin.on('end', () => resolve(data));
|
|
17
|
+
});
|
|
18
|
+
// TODO: Parse transcript, apply classification logic, prompt agent to save
|
|
19
|
+
// For now, output the classification prompt for the agent
|
|
20
|
+
console.log(`[reqall] Project: ${projectName}`);
|
|
21
|
+
console.log(CLASSIFICATION_PROMPT);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// Non-blocking: exit cleanly on any error
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
main();
|
|
29
|
+
//# sourceMappingURL=classify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify.js","sourceRoot":"","sources":["../../hooks/classify.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAEhF,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,aAAa,EAAE,CAAC;QAE1D,6BAA6B;QAC7B,MAAM,KAAK,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;YAClD,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,2EAA2E;QAC3E,0DAA0D;QAC1D,OAAO,CAAC,GAAG,CAAC,qBAAqB,WAAW,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,0CAA0C;QAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// ../core/dist/config.js
|
|
2
|
+
var DEFAULT_URL = "https://reqall.net";
|
|
3
|
+
var DEFAULT_CONTEXT_LIMIT = 5;
|
|
4
|
+
var DEFAULT_RECENCY_HOURS = 1;
|
|
5
|
+
function loadConfig() {
|
|
6
|
+
const apiKey = process.env.REQALL_API_KEY;
|
|
7
|
+
if (!apiKey) {
|
|
8
|
+
throw new Error("REQALL_API_KEY environment variable is required");
|
|
9
|
+
}
|
|
10
|
+
return {
|
|
11
|
+
apiKey,
|
|
12
|
+
url: process.env.REQALL_URL || DEFAULT_URL,
|
|
13
|
+
projectName: process.env.REQALL_PROJECT_NAME || void 0,
|
|
14
|
+
contextLimit: parseInt(process.env.REQALL_CONTEXT_LIMIT || "", 10) || DEFAULT_CONTEXT_LIMIT,
|
|
15
|
+
recencyHours: parseInt(process.env.REQALL_RECENCY_HOURS || "", 10) || DEFAULT_RECENCY_HOURS
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// ../core/dist/detect-project.js
|
|
20
|
+
import { execSync } from "node:child_process";
|
|
21
|
+
import { basename } from "node:path";
|
|
22
|
+
function detectProject(cwd) {
|
|
23
|
+
if (process.env.REQALL_PROJECT_NAME) {
|
|
24
|
+
return process.env.REQALL_PROJECT_NAME;
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const remote = execSync("git remote get-url origin", {
|
|
28
|
+
cwd: cwd || process.cwd(),
|
|
29
|
+
encoding: "utf-8",
|
|
30
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
31
|
+
}).trim();
|
|
32
|
+
const match = remote.match(/[:/]([^/]+\/[^/]+?)(?:\.git)?$/);
|
|
33
|
+
if (match) {
|
|
34
|
+
return match[1];
|
|
35
|
+
}
|
|
36
|
+
} catch {
|
|
37
|
+
}
|
|
38
|
+
return basename(cwd || process.cwd());
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ../core/dist/classify.js
|
|
42
|
+
var CLASSIFICATION_PROMPT = `Classify the work just completed into exactly one category:
|
|
43
|
+
|
|
44
|
+
| Work type | kind | status |
|
|
45
|
+
|------------------------------------|---------|------------|
|
|
46
|
+
| Bug fix | issue | resolved |
|
|
47
|
+
| Architectural change | arch | resolved |
|
|
48
|
+
| New feature request (not yet done) | todo | open |
|
|
49
|
+
| Completed feature request | todo | resolved |
|
|
50
|
+
| New spec or plan | spec | open |
|
|
51
|
+
| Trivial / Q&A / unclassifiable | \u2014 | no action |
|
|
52
|
+
|
|
53
|
+
If the work is non-trivial, save it via reqall:upsert_record with the appropriate kind, status, and a short descriptive title.
|
|
54
|
+
If the work created or modified relationships between records, also call reqall:upsert_edge.`;
|
|
55
|
+
|
|
56
|
+
// dist/hooks/classify.js
|
|
57
|
+
async function main() {
|
|
58
|
+
try {
|
|
59
|
+
const config = loadConfig();
|
|
60
|
+
const projectName = config.projectName || detectProject();
|
|
61
|
+
const input = await new Promise((resolve) => {
|
|
62
|
+
let data = "";
|
|
63
|
+
process.stdin.on("data", (chunk) => {
|
|
64
|
+
data += chunk;
|
|
65
|
+
});
|
|
66
|
+
process.stdin.on("end", () => resolve(data));
|
|
67
|
+
});
|
|
68
|
+
console.log(`[reqall] Project: ${projectName}`);
|
|
69
|
+
console.log(CLASSIFICATION_PROMPT);
|
|
70
|
+
} catch {
|
|
71
|
+
process.exit(0);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
main();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../hooks/context.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UserPromptSubmit hook — Context Retrieval (pre-prompt)
|
|
3
|
+
*
|
|
4
|
+
* Reads the user's prompt from stdin, searches Reqall for relevant records,
|
|
5
|
+
* and outputs context lines for the agent to see.
|
|
6
|
+
*/
|
|
7
|
+
import { loadConfig, detectProject } from '@reqall/core';
|
|
8
|
+
async function main() {
|
|
9
|
+
try {
|
|
10
|
+
const config = loadConfig();
|
|
11
|
+
const projectName = config.projectName || detectProject();
|
|
12
|
+
// Read stdin JSON from Claude Code
|
|
13
|
+
const input = await new Promise((resolve) => {
|
|
14
|
+
let data = '';
|
|
15
|
+
process.stdin.on('data', (chunk) => { data += chunk; });
|
|
16
|
+
process.stdin.on('end', () => resolve(data));
|
|
17
|
+
});
|
|
18
|
+
const { prompt } = JSON.parse(input);
|
|
19
|
+
// TODO: Call reqall MCP tools via HTTP to fetch context
|
|
20
|
+
// 1. list_records for recent records in this project
|
|
21
|
+
// 2. search with the prompt text for semantic matches
|
|
22
|
+
// 3. Format and output
|
|
23
|
+
// Placeholder output until MCP client is implemented
|
|
24
|
+
console.log(`[reqall] Project: ${projectName}`);
|
|
25
|
+
console.log(`[reqall] Context retrieval ready — MCP client pending implementation`);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Non-blocking: exit cleanly on any error
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
main();
|
|
33
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../hooks/context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAiB,MAAM,cAAc,CAAC;AAExE,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,aAAa,EAAE,CAAC;QAE1D,mCAAmC;QACnC,MAAM,KAAK,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;YAClD,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAErC,wDAAwD;QACxD,qDAAqD;QACrD,sDAAsD;QACtD,uBAAuB;QAEvB,qDAAqD;QACrD,OAAO,CAAC,GAAG,CAAC,qBAAqB,WAAW,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,sEAAsE,CAAC,CAAC;IACtF,CAAC;IAAC,MAAM,CAAC;QACP,0CAA0C;QAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// ../core/dist/config.js
|
|
2
|
+
var DEFAULT_URL = "https://reqall.net";
|
|
3
|
+
var DEFAULT_CONTEXT_LIMIT = 5;
|
|
4
|
+
var DEFAULT_RECENCY_HOURS = 1;
|
|
5
|
+
function loadConfig() {
|
|
6
|
+
const apiKey = process.env.REQALL_API_KEY;
|
|
7
|
+
if (!apiKey) {
|
|
8
|
+
throw new Error("REQALL_API_KEY environment variable is required");
|
|
9
|
+
}
|
|
10
|
+
return {
|
|
11
|
+
apiKey,
|
|
12
|
+
url: process.env.REQALL_URL || DEFAULT_URL,
|
|
13
|
+
projectName: process.env.REQALL_PROJECT_NAME || void 0,
|
|
14
|
+
contextLimit: parseInt(process.env.REQALL_CONTEXT_LIMIT || "", 10) || DEFAULT_CONTEXT_LIMIT,
|
|
15
|
+
recencyHours: parseInt(process.env.REQALL_RECENCY_HOURS || "", 10) || DEFAULT_RECENCY_HOURS
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// ../core/dist/detect-project.js
|
|
20
|
+
import { execSync } from "node:child_process";
|
|
21
|
+
import { basename } from "node:path";
|
|
22
|
+
function detectProject(cwd) {
|
|
23
|
+
if (process.env.REQALL_PROJECT_NAME) {
|
|
24
|
+
return process.env.REQALL_PROJECT_NAME;
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const remote = execSync("git remote get-url origin", {
|
|
28
|
+
cwd: cwd || process.cwd(),
|
|
29
|
+
encoding: "utf-8",
|
|
30
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
31
|
+
}).trim();
|
|
32
|
+
const match = remote.match(/[:/]([^/]+\/[^/]+?)(?:\.git)?$/);
|
|
33
|
+
if (match) {
|
|
34
|
+
return match[1];
|
|
35
|
+
}
|
|
36
|
+
} catch {
|
|
37
|
+
}
|
|
38
|
+
return basename(cwd || process.cwd());
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// dist/hooks/context.js
|
|
42
|
+
async function main() {
|
|
43
|
+
try {
|
|
44
|
+
const config = loadConfig();
|
|
45
|
+
const projectName = config.projectName || detectProject();
|
|
46
|
+
const input = await new Promise((resolve) => {
|
|
47
|
+
let data = "";
|
|
48
|
+
process.stdin.on("data", (chunk) => {
|
|
49
|
+
data += chunk;
|
|
50
|
+
});
|
|
51
|
+
process.stdin.on("end", () => resolve(data));
|
|
52
|
+
});
|
|
53
|
+
const { prompt } = JSON.parse(input);
|
|
54
|
+
console.log(`[reqall] Project: ${projectName}`);
|
|
55
|
+
console.log(`[reqall] Context retrieval ready \u2014 MCP client pending implementation`);
|
|
56
|
+
} catch {
|
|
57
|
+
process.exit(0);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
main();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../hooks/plan.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SubagentStop hook — Plan Capture (post-plan)
|
|
3
|
+
*
|
|
4
|
+
* Triggered when a planning subagent completes. Reads the plan transcript
|
|
5
|
+
* and prompts the agent to persist it as a spec record.
|
|
6
|
+
*/
|
|
7
|
+
import { loadConfig, detectProject } from '@reqall/core';
|
|
8
|
+
async function main() {
|
|
9
|
+
try {
|
|
10
|
+
const config = loadConfig();
|
|
11
|
+
const projectName = config.projectName || detectProject();
|
|
12
|
+
// Read plan transcript from stdin
|
|
13
|
+
const input = await new Promise((resolve) => {
|
|
14
|
+
let data = '';
|
|
15
|
+
process.stdin.on('data', (chunk) => { data += chunk; });
|
|
16
|
+
process.stdin.on('end', () => resolve(data));
|
|
17
|
+
});
|
|
18
|
+
if (!input.trim()) {
|
|
19
|
+
// Empty transcript — skip silently
|
|
20
|
+
process.exit(0);
|
|
21
|
+
}
|
|
22
|
+
// TODO: Extract plan title and details from transcript
|
|
23
|
+
// Prompt agent to save via reqall:upsert_record with kind=spec, status=open
|
|
24
|
+
console.log(`[reqall] Project: ${projectName}`);
|
|
25
|
+
console.log(`[reqall] Plan detected — save as spec record via reqall:upsert_record with kind=spec, status=open`);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Non-blocking: exit cleanly on any error
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
main();
|
|
33
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../hooks/plan.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEzD,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,aAAa,EAAE,CAAC;QAE1D,kCAAkC;QAClC,MAAM,KAAK,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;YAClD,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YAClB,mCAAmC;YACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,uDAAuD;QACvD,4EAA4E;QAE5E,OAAO,CAAC,GAAG,CAAC,qBAAqB,WAAW,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,mGAAmG,CAAC,CAAC;IACnH,CAAC;IAAC,MAAM,CAAC;QACP,0CAA0C;QAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// ../core/dist/config.js
|
|
2
|
+
var DEFAULT_URL = "https://reqall.net";
|
|
3
|
+
var DEFAULT_CONTEXT_LIMIT = 5;
|
|
4
|
+
var DEFAULT_RECENCY_HOURS = 1;
|
|
5
|
+
function loadConfig() {
|
|
6
|
+
const apiKey = process.env.REQALL_API_KEY;
|
|
7
|
+
if (!apiKey) {
|
|
8
|
+
throw new Error("REQALL_API_KEY environment variable is required");
|
|
9
|
+
}
|
|
10
|
+
return {
|
|
11
|
+
apiKey,
|
|
12
|
+
url: process.env.REQALL_URL || DEFAULT_URL,
|
|
13
|
+
projectName: process.env.REQALL_PROJECT_NAME || void 0,
|
|
14
|
+
contextLimit: parseInt(process.env.REQALL_CONTEXT_LIMIT || "", 10) || DEFAULT_CONTEXT_LIMIT,
|
|
15
|
+
recencyHours: parseInt(process.env.REQALL_RECENCY_HOURS || "", 10) || DEFAULT_RECENCY_HOURS
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// ../core/dist/detect-project.js
|
|
20
|
+
import { execSync } from "node:child_process";
|
|
21
|
+
import { basename } from "node:path";
|
|
22
|
+
function detectProject(cwd) {
|
|
23
|
+
if (process.env.REQALL_PROJECT_NAME) {
|
|
24
|
+
return process.env.REQALL_PROJECT_NAME;
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const remote = execSync("git remote get-url origin", {
|
|
28
|
+
cwd: cwd || process.cwd(),
|
|
29
|
+
encoding: "utf-8",
|
|
30
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
31
|
+
}).trim();
|
|
32
|
+
const match = remote.match(/[:/]([^/]+\/[^/]+?)(?:\.git)?$/);
|
|
33
|
+
if (match) {
|
|
34
|
+
return match[1];
|
|
35
|
+
}
|
|
36
|
+
} catch {
|
|
37
|
+
}
|
|
38
|
+
return basename(cwd || process.cwd());
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// dist/hooks/plan.js
|
|
42
|
+
async function main() {
|
|
43
|
+
try {
|
|
44
|
+
const config = loadConfig();
|
|
45
|
+
const projectName = config.projectName || detectProject();
|
|
46
|
+
const input = await new Promise((resolve) => {
|
|
47
|
+
let data = "";
|
|
48
|
+
process.stdin.on("data", (chunk) => {
|
|
49
|
+
data += chunk;
|
|
50
|
+
});
|
|
51
|
+
process.stdin.on("end", () => resolve(data));
|
|
52
|
+
});
|
|
53
|
+
if (!input.trim()) {
|
|
54
|
+
process.exit(0);
|
|
55
|
+
}
|
|
56
|
+
console.log(`[reqall] Project: ${projectName}`);
|
|
57
|
+
console.log(`[reqall] Plan detected \u2014 save as spec record via reqall:upsert_record with kind=spec, status=open`);
|
|
58
|
+
} catch {
|
|
59
|
+
process.exit(0);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
main();
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stop hook — Work Classification (post-task)
|
|
3
|
+
*
|
|
4
|
+
* Reads the agent's session transcript and classifies the work done.
|
|
5
|
+
* Outputs a prompt for the agent to persist the classification via MCP tools.
|
|
6
|
+
*/
|
|
7
|
+
import { loadConfig, detectProject, CLASSIFICATION_PROMPT } from '@reqall/core';
|
|
8
|
+
|
|
9
|
+
async function main() {
|
|
10
|
+
try {
|
|
11
|
+
const config = loadConfig();
|
|
12
|
+
const projectName = config.projectName || detectProject();
|
|
13
|
+
|
|
14
|
+
// Read transcript from stdin
|
|
15
|
+
const input = await new Promise<string>((resolve) => {
|
|
16
|
+
let data = '';
|
|
17
|
+
process.stdin.on('data', (chunk) => { data += chunk; });
|
|
18
|
+
process.stdin.on('end', () => resolve(data));
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// TODO: Parse transcript, apply classification logic, prompt agent to save
|
|
22
|
+
// For now, output the classification prompt for the agent
|
|
23
|
+
console.log(`[reqall] Project: ${projectName}`);
|
|
24
|
+
console.log(CLASSIFICATION_PROMPT);
|
|
25
|
+
} catch {
|
|
26
|
+
// Non-blocking: exit cleanly on any error
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
main();
|
package/hooks/context.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UserPromptSubmit hook — Context Retrieval (pre-prompt)
|
|
3
|
+
*
|
|
4
|
+
* Reads the user's prompt from stdin, searches Reqall for relevant records,
|
|
5
|
+
* and outputs context lines for the agent to see.
|
|
6
|
+
*/
|
|
7
|
+
import { loadConfig, detectProject, formatContext } from '@reqall/core';
|
|
8
|
+
|
|
9
|
+
async function main() {
|
|
10
|
+
try {
|
|
11
|
+
const config = loadConfig();
|
|
12
|
+
const projectName = config.projectName || detectProject();
|
|
13
|
+
|
|
14
|
+
// Read stdin JSON from Claude Code
|
|
15
|
+
const input = await new Promise<string>((resolve) => {
|
|
16
|
+
let data = '';
|
|
17
|
+
process.stdin.on('data', (chunk) => { data += chunk; });
|
|
18
|
+
process.stdin.on('end', () => resolve(data));
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const { prompt } = JSON.parse(input);
|
|
22
|
+
|
|
23
|
+
// TODO: Call reqall MCP tools via HTTP to fetch context
|
|
24
|
+
// 1. list_records for recent records in this project
|
|
25
|
+
// 2. search with the prompt text for semantic matches
|
|
26
|
+
// 3. Format and output
|
|
27
|
+
|
|
28
|
+
// Placeholder output until MCP client is implemented
|
|
29
|
+
console.log(`[reqall] Project: ${projectName}`);
|
|
30
|
+
console.log(`[reqall] Context retrieval ready — MCP client pending implementation`);
|
|
31
|
+
} catch {
|
|
32
|
+
// Non-blocking: exit cleanly on any error
|
|
33
|
+
process.exit(0);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
main();
|
package/hooks/hooks.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": [
|
|
3
|
+
{
|
|
4
|
+
"event": "UserPromptSubmit",
|
|
5
|
+
"type": "command",
|
|
6
|
+
"command": "node dist/hooks/context.mjs"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"event": "Stop",
|
|
10
|
+
"type": "agent",
|
|
11
|
+
"command": "node dist/hooks/classify.mjs"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"event": "SubagentStop",
|
|
15
|
+
"matcher": "Plan",
|
|
16
|
+
"type": "agent",
|
|
17
|
+
"command": "node dist/hooks/plan.mjs"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
package/hooks/plan.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SubagentStop hook — Plan Capture (post-plan)
|
|
3
|
+
*
|
|
4
|
+
* Triggered when a planning subagent completes. Reads the plan transcript
|
|
5
|
+
* and prompts the agent to persist it as a spec record.
|
|
6
|
+
*/
|
|
7
|
+
import { loadConfig, detectProject } from '@reqall/core';
|
|
8
|
+
|
|
9
|
+
async function main() {
|
|
10
|
+
try {
|
|
11
|
+
const config = loadConfig();
|
|
12
|
+
const projectName = config.projectName || detectProject();
|
|
13
|
+
|
|
14
|
+
// Read plan transcript from stdin
|
|
15
|
+
const input = await new Promise<string>((resolve) => {
|
|
16
|
+
let data = '';
|
|
17
|
+
process.stdin.on('data', (chunk) => { data += chunk; });
|
|
18
|
+
process.stdin.on('end', () => resolve(data));
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
if (!input.trim()) {
|
|
22
|
+
// Empty transcript — skip silently
|
|
23
|
+
process.exit(0);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// TODO: Extract plan title and details from transcript
|
|
27
|
+
// Prompt agent to save via reqall:upsert_record with kind=spec, status=open
|
|
28
|
+
|
|
29
|
+
console.log(`[reqall] Project: ${projectName}`);
|
|
30
|
+
console.log(`[reqall] Plan detected — save as spec record via reqall:upsert_record with kind=spec, status=open`);
|
|
31
|
+
} catch {
|
|
32
|
+
// Non-blocking: exit cleanly on any error
|
|
33
|
+
process.exit(0);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
main();
|
package/mcp-servers.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reqall/claude-plugin",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Reqall plugin for Claude Code — persistent semantic memory for AI agents",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"reqall-claude-plugin": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@reqall/core": "0.0.1"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"esbuild": "^0.25.0"
|
|
15
|
+
},
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc && node scripts/bundle-hooks.js",
|
|
19
|
+
"clean": "rm -rf dist"
|
|
20
|
+
}
|
|
21
|
+
}
|
package/plugin.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundle each hook script into a self-contained .mjs file using esbuild.
|
|
3
|
+
* This inlines @reqall/core since Claude Code copies plugins without node_modules.
|
|
4
|
+
*/
|
|
5
|
+
import { build } from 'esbuild';
|
|
6
|
+
import { readdirSync } from 'node:fs';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
|
|
9
|
+
const hooksDir = join(import.meta.dirname, '..', 'dist', 'hooks');
|
|
10
|
+
const outDir = join(import.meta.dirname, '..', 'dist', 'hooks');
|
|
11
|
+
|
|
12
|
+
const hookFiles = readdirSync(hooksDir).filter(f => f.endsWith('.js') && f !== 'hooks.json');
|
|
13
|
+
|
|
14
|
+
for (const file of hookFiles) {
|
|
15
|
+
const name = file.replace('.js', '.mjs');
|
|
16
|
+
await build({
|
|
17
|
+
entryPoints: [join(hooksDir, file)],
|
|
18
|
+
bundle: true,
|
|
19
|
+
platform: 'node',
|
|
20
|
+
format: 'esm',
|
|
21
|
+
outfile: join(outDir, name),
|
|
22
|
+
external: [],
|
|
23
|
+
});
|
|
24
|
+
console.log(`Bundled: ${name}`);
|
|
25
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reqall:issues
|
|
3
|
+
description: Create, list, search, and update issues tracked in Reqall
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Issue Tracking
|
|
7
|
+
|
|
8
|
+
Track and manage issues using the Reqall knowledgebase. Issues represent bugs, tasks, blockers, and problems within projects.
|
|
9
|
+
|
|
10
|
+
## Conventions
|
|
11
|
+
|
|
12
|
+
Use title prefixes to categorize issues:
|
|
13
|
+
- `BUG:` — Defects to fix
|
|
14
|
+
- `TASK:` — Work items
|
|
15
|
+
- `BLOCKER:` — Critical blockers
|
|
16
|
+
- `QUESTION:` — Unknowns to resolve
|
|
17
|
+
|
|
18
|
+
## Workflows
|
|
19
|
+
|
|
20
|
+
### Create an issue
|
|
21
|
+
```
|
|
22
|
+
reqall:upsert_record { kind: "issue", title: "BUG: ...", body: "...", status: "open" }
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### List open issues
|
|
26
|
+
```
|
|
27
|
+
reqall:list_records { kind: "issue", status: "open" }
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Search for issues
|
|
31
|
+
```
|
|
32
|
+
reqall:search { query: "...", kind: "issue" }
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Resolve an issue
|
|
36
|
+
```
|
|
37
|
+
reqall:upsert_record { id: <issue_id>, status: "resolved" }
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Link related issues
|
|
41
|
+
```
|
|
42
|
+
reqall:upsert_edge { source_id: <id>, source_table: "records", target_id: <id>, target_table: "records", relationship: "blocks" }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Related Skills
|
|
46
|
+
- `reqall:review-issues` — Interactive issue grooming session
|
|
47
|
+
- `reqall:specs` — Document requirements and architecture decisions
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reqall:projects
|
|
3
|
+
description: List projects, view records by project, manage project context
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Project Management
|
|
7
|
+
|
|
8
|
+
Explore and manage projects in the Reqall knowledgebase.
|
|
9
|
+
|
|
10
|
+
## Workflows
|
|
11
|
+
|
|
12
|
+
### List all projects
|
|
13
|
+
```
|
|
14
|
+
reqall:list_projects
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### View records for a project
|
|
18
|
+
```
|
|
19
|
+
reqall:list_records { project_id: <project_id> }
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Create a new project
|
|
23
|
+
```
|
|
24
|
+
reqall:upsert_project { name: "org/repo" }
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Search across projects
|
|
28
|
+
```
|
|
29
|
+
reqall:search { query: "..." }
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### View project impact graph
|
|
33
|
+
```
|
|
34
|
+
reqall:impact { entity_id: <project_id>, entity_type: "projects" }
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Related Skills
|
|
38
|
+
- `reqall:issues` — Track bugs, tasks, and blockers
|
|
39
|
+
- `reqall:specs` — Document requirements and architecture decisions
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reqall:review-issues
|
|
3
|
+
description: Interactive issue review and grooming session
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Issue Review
|
|
7
|
+
|
|
8
|
+
Walk through all open issues for the current project and triage them interactively.
|
|
9
|
+
|
|
10
|
+
## Process
|
|
11
|
+
|
|
12
|
+
1. Fetch all open issues for the current project:
|
|
13
|
+
```
|
|
14
|
+
reqall:list_records { kind: "issue", status: "open" }
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
2. For each issue, present it to the user and ask:
|
|
18
|
+
- Is this still relevant?
|
|
19
|
+
- Should the status change (resolve, archive)?
|
|
20
|
+
- Does it need more detail or context?
|
|
21
|
+
- Are there related issues to link?
|
|
22
|
+
|
|
23
|
+
3. Apply updates as directed:
|
|
24
|
+
```
|
|
25
|
+
reqall:upsert_record { id: <issue_id>, status: "resolved" }
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
4. Summarize changes made during the review session.
|
|
29
|
+
|
|
30
|
+
## Related Skills
|
|
31
|
+
- `reqall:issues` — Create and manage individual issues
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reqall:review-specs
|
|
3
|
+
description: Interactive specification review and validation session
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Specification Review
|
|
7
|
+
|
|
8
|
+
Walk through all specifications for the current project and validate them interactively.
|
|
9
|
+
|
|
10
|
+
## Process
|
|
11
|
+
|
|
12
|
+
1. Fetch all specifications for the current project:
|
|
13
|
+
```
|
|
14
|
+
reqall:list_records { kind: "spec" }
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
2. For each spec, present it to the user and ask:
|
|
18
|
+
- Is this still accurate?
|
|
19
|
+
- Does it need updating based on recent changes?
|
|
20
|
+
- Should it be archived?
|
|
21
|
+
- Are there missing links to implementations or tests?
|
|
22
|
+
|
|
23
|
+
3. Apply updates as directed:
|
|
24
|
+
```
|
|
25
|
+
reqall:upsert_record { id: <spec_id>, body: "updated text...", status: "open" }
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
4. Summarize changes made during the review session.
|
|
29
|
+
|
|
30
|
+
## Related Skills
|
|
31
|
+
- `reqall:specs` — Create and manage individual specifications
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reqall:specs
|
|
3
|
+
description: Document requirements and architecture decisions in Reqall
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Specification Management
|
|
7
|
+
|
|
8
|
+
Document requirements, architecture decisions, API contracts, and design patterns using Reqall.
|
|
9
|
+
|
|
10
|
+
## Conventions
|
|
11
|
+
|
|
12
|
+
Use title prefixes to categorize specifications:
|
|
13
|
+
- `ARCH:` — Architecture decisions
|
|
14
|
+
- `API:` — API contracts
|
|
15
|
+
- `AUTH:` — Authentication/authorization
|
|
16
|
+
- `DATA:` — Data models/schemas
|
|
17
|
+
- `UI:` — User interface patterns
|
|
18
|
+
|
|
19
|
+
## Workflows
|
|
20
|
+
|
|
21
|
+
### Create a specification
|
|
22
|
+
```
|
|
23
|
+
reqall:upsert_record { kind: "spec", title: "ARCH: ...", body: "...", status: "open" }
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### List specifications
|
|
27
|
+
```
|
|
28
|
+
reqall:list_records { kind: "spec" }
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Search for specs
|
|
32
|
+
```
|
|
33
|
+
reqall:search { query: "...", kind: "spec" }
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Link a spec to its implementation
|
|
37
|
+
```
|
|
38
|
+
reqall:upsert_edge { source_id: <spec_id>, source_table: "records", target_id: <impl_id>, target_table: "records", relationship: "implements" }
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Related Skills
|
|
42
|
+
- `reqall:review-specs` — Interactive spec review and validation session
|
|
43
|
+
- `reqall:issues` — Track bugs, tasks, and blockers
|