qualitative-research-pro 1.0.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/AGENTS.md +108 -0
- package/CLAUDE.md +171 -0
- package/LICENSE +21 -0
- package/README.md +166 -0
- package/agents/analysis-orchestrator.md +162 -0
- package/agents/audit-trail-builder.md +127 -0
- package/agents/category-developer.md +179 -0
- package/agents/citation-manager.md +83 -0
- package/agents/constant-comparator.md +135 -0
- package/agents/data-manager.md +104 -0
- package/agents/discussion-writer.md +128 -0
- package/agents/document-analyst.md +114 -0
- package/agents/ethics-reviewer.md +119 -0
- package/agents/field-note-analyst.md +124 -0
- package/agents/fit-assessor.md +192 -0
- package/agents/grounded-theorist.md +210 -0
- package/agents/literature-integrator.md +169 -0
- package/agents/literature-reviewer.md +112 -0
- package/agents/memo-writer.md +234 -0
- package/agents/methodology-critic.md +166 -0
- package/agents/methods-writer.md +109 -0
- package/agents/open-coder.md +187 -0
- package/agents/pattern-analyst.md +166 -0
- package/agents/peer-reviewer.md +129 -0
- package/agents/planner.md +122 -0
- package/agents/proposal-writer.md +108 -0
- package/agents/reflexivity-auditor.md +128 -0
- package/agents/research-designer.md +164 -0
- package/agents/research-writer.md +100 -0
- package/agents/saturation-assessor.md +159 -0
- package/agents/selective-coder.md +167 -0
- package/agents/theoretical-coder.md +260 -0
- package/agents/theoretical-sampler.md +165 -0
- package/agents/transcript-analyst.md +123 -0
- package/bin/cli.mjs +236 -0
- package/hooks/dist/agent-memory-loader.mjs +94 -0
- package/hooks/dist/agent-memory-saver.mjs +113 -0
- package/hooks/dist/bash-audit-log.mjs +71 -0
- package/hooks/dist/credential-deny.mjs +165 -0
- package/hooks/dist/forge-compile-check.mjs +92 -0
- package/hooks/dist/gas-snapshot-diff.mjs +71 -0
- package/hooks/dist/memory-awareness.mjs +276 -0
- package/hooks/dist/natspec-enforcer.mjs +67 -0
- package/hooks/dist/passive-learner.mjs +220 -0
- package/hooks/dist/pre-compact-continuity.mjs +467 -0
- package/hooks/dist/sast-on-edit.mjs +230 -0
- package/hooks/dist/session-analytics.mjs +84 -0
- package/hooks/dist/session-end-cleanup.mjs +121 -0
- package/hooks/dist/session-outcome.mjs +84 -0
- package/hooks/dist/session-register.mjs +307 -0
- package/hooks/dist/session-start-continuity.mjs +405 -0
- package/hooks/dist/slither-on-save.mjs +87 -0
- package/hooks/dist/storage-layout-check.mjs +89 -0
- package/hooks/dist/transcript-parser.mjs +214 -0
- package/install.sh +194 -0
- package/package.json +46 -0
- package/plugin.json +19 -0
- package/rules/academic-writing-style.md +42 -0
- package/rules/citation-standards.md +47 -0
- package/rules/current-methodological-state.md +40 -0
- package/rules/data-handling.md +44 -0
- package/rules/finding-output-format.md +47 -0
- package/rules/gt-coding-standards.md +40 -0
- package/rules/methodological-rigor.md +56 -0
- package/rules/quality-criteria.md +41 -0
- package/rules/reflexivity-requirements.md +40 -0
- package/rules/research-ethics-standards.md +44 -0
- package/skills/.gitkeep +2 -0
- package/skills/academic-writing/SKILL.md +73 -0
- package/skills/action-research/SKILL.md +96 -0
- package/skills/apa-formatting/SKILL.md +85 -0
- package/skills/case-study-methods/SKILL.md +96 -0
- package/skills/category-development/SKILL.md +80 -0
- package/skills/chicago-formatting/SKILL.md +81 -0
- package/skills/coding-pipeline/SKILL.md +81 -0
- package/skills/conceptual-frameworks/SKILL.md +70 -0
- package/skills/constant-comparison/SKILL.md +188 -0
- package/skills/constructivist-gt/SKILL.md +91 -0
- package/skills/data-management-protocols/SKILL.md +67 -0
- package/skills/document-analysis/SKILL.md +66 -0
- package/skills/ethnographic-methods/SKILL.md +82 -0
- package/skills/focus-group-methods/SKILL.md +66 -0
- package/skills/formal-theory/SKILL.md +159 -0
- package/skills/glaserian-grounded-theory/SKILL.md +212 -0
- package/skills/interview-design/SKILL.md +67 -0
- package/skills/literature-synthesis/SKILL.md +71 -0
- package/skills/member-checking/SKILL.md +66 -0
- package/skills/memo-writing/SKILL.md +158 -0
- package/skills/mixed-methods-design/SKILL.md +69 -0
- package/skills/narrative-inquiry/SKILL.md +101 -0
- package/skills/observation-methods/SKILL.md +67 -0
- package/skills/open-coding/SKILL.md +176 -0
- package/skills/paradigmatic-positioning/SKILL.md +72 -0
- package/skills/peer-debriefing/SKILL.md +72 -0
- package/skills/phenomenological-methods/SKILL.md +91 -0
- package/skills/qualitative-rigor/SKILL.md +78 -0
- package/skills/reflexive-practice/SKILL.md +64 -0
- package/skills/research-ethics/SKILL.md +64 -0
- package/skills/research-proposal-writing/SKILL.md +81 -0
- package/skills/research-questions/SKILL.md +66 -0
- package/skills/sampling-strategies/SKILL.md +61 -0
- package/skills/selective-coding/SKILL.md +183 -0
- package/skills/situational-analysis/SKILL.md +93 -0
- package/skills/substantive-theory/SKILL.md +169 -0
- package/skills/thematic-analysis/SKILL.md +80 -0
- package/skills/theoretical-coding/SKILL.md +213 -0
- package/skills/theoretical-sampling/SKILL.md +152 -0
- package/skills/theoretical-saturation/SKILL.md +179 -0
- package/skills/theoretical-sensitivity/SKILL.md +175 -0
- package/skills/theory-integration/SKILL.md +85 -0
- package/skills/thick-description/SKILL.md +69 -0
- package/skills/triangulation/SKILL.md +65 -0
- package/skills/visual-modeling/SKILL.md +66 -0
- package/skills/vulnerable-populations/SKILL.md +69 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
// src/transcript-parser.ts
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
function parseTranscript(transcriptPath) {
|
|
4
|
+
const summary = {
|
|
5
|
+
lastTodos: [],
|
|
6
|
+
recentToolCalls: [],
|
|
7
|
+
lastAssistantMessage: "",
|
|
8
|
+
filesModified: [],
|
|
9
|
+
errorsEncountered: []
|
|
10
|
+
};
|
|
11
|
+
if (!fs.existsSync(transcriptPath)) {
|
|
12
|
+
return summary;
|
|
13
|
+
}
|
|
14
|
+
const content = fs.readFileSync(transcriptPath, "utf-8");
|
|
15
|
+
const lines = content.split("\n").filter((line) => line.trim());
|
|
16
|
+
const allToolCalls = [];
|
|
17
|
+
const modifiedFiles = /* @__PURE__ */ new Set();
|
|
18
|
+
const errors = [];
|
|
19
|
+
let lastTodoState = [];
|
|
20
|
+
let lastAssistant = "";
|
|
21
|
+
for (const line of lines) {
|
|
22
|
+
try {
|
|
23
|
+
const entry = JSON.parse(line);
|
|
24
|
+
if (entry.role === "assistant" && typeof entry.content === "string") {
|
|
25
|
+
lastAssistant = entry.content;
|
|
26
|
+
} else if (entry.type === "assistant" && typeof entry.content === "string") {
|
|
27
|
+
lastAssistant = entry.content;
|
|
28
|
+
}
|
|
29
|
+
if (entry.tool_name || entry.type === "tool_use") {
|
|
30
|
+
const toolName = entry.tool_name || entry.name;
|
|
31
|
+
if (toolName) {
|
|
32
|
+
const toolCall = {
|
|
33
|
+
name: toolName,
|
|
34
|
+
timestamp: entry.timestamp,
|
|
35
|
+
input: entry.tool_input,
|
|
36
|
+
success: true
|
|
37
|
+
// Will be updated by result
|
|
38
|
+
};
|
|
39
|
+
if (toolName === "TodoWrite" || toolName.toLowerCase().includes("todowrite")) {
|
|
40
|
+
const input = entry.tool_input;
|
|
41
|
+
if (input?.todos) {
|
|
42
|
+
lastTodoState = input.todos.map((t, idx) => ({
|
|
43
|
+
id: t.id || `todo-${idx}`,
|
|
44
|
+
content: t.content || "",
|
|
45
|
+
status: t.status || "pending"
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (toolName === "Edit" || toolName === "Write" || toolName.toLowerCase().includes("edit") || toolName.toLowerCase().includes("write")) {
|
|
50
|
+
const input = entry.tool_input;
|
|
51
|
+
const filePath = input?.file_path || input?.path;
|
|
52
|
+
if (filePath && typeof filePath === "string") {
|
|
53
|
+
modifiedFiles.add(filePath);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (toolName === "Bash" || toolName.toLowerCase().includes("bash")) {
|
|
57
|
+
const input = entry.tool_input;
|
|
58
|
+
if (input?.command) {
|
|
59
|
+
toolCall.input = { command: input.command };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
allToolCalls.push(toolCall);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (entry.type === "tool_result" || entry.tool_result !== void 0) {
|
|
66
|
+
const result = entry.tool_result;
|
|
67
|
+
if (result) {
|
|
68
|
+
const exitCode = result.exit_code ?? result.exitCode;
|
|
69
|
+
if (exitCode !== void 0 && exitCode !== 0) {
|
|
70
|
+
if (allToolCalls.length > 0) {
|
|
71
|
+
allToolCalls[allToolCalls.length - 1].success = false;
|
|
72
|
+
}
|
|
73
|
+
const errorMsg = result.stderr || result.error || "Command failed";
|
|
74
|
+
const lastTool = allToolCalls[allToolCalls.length - 1];
|
|
75
|
+
const command = lastTool?.input?.command || "unknown command";
|
|
76
|
+
errors.push(`${command}: ${errorMsg.substring(0, 200)}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (entry.error) {
|
|
80
|
+
errors.push(entry.error.substring(0, 200));
|
|
81
|
+
if (allToolCalls.length > 0) {
|
|
82
|
+
allToolCalls[allToolCalls.length - 1].success = false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
} catch {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
summary.lastTodos = lastTodoState;
|
|
91
|
+
summary.recentToolCalls = allToolCalls.slice(-5);
|
|
92
|
+
summary.lastAssistantMessage = lastAssistant.substring(0, 500);
|
|
93
|
+
summary.filesModified = Array.from(modifiedFiles);
|
|
94
|
+
summary.errorsEncountered = errors.slice(-5);
|
|
95
|
+
return summary;
|
|
96
|
+
}
|
|
97
|
+
function generateAutoHandoff(summary, sessionName) {
|
|
98
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
99
|
+
const dateOnly = timestamp.split("T")[0];
|
|
100
|
+
const lines = [];
|
|
101
|
+
const inProgress = summary.lastTodos.filter((t) => t.status === "in_progress");
|
|
102
|
+
const pending = summary.lastTodos.filter((t) => t.status === "pending");
|
|
103
|
+
const completed = summary.lastTodos.filter((t) => t.status === "completed");
|
|
104
|
+
const currentTask = inProgress[0]?.content || pending[0]?.content || "Continue from auto-compact";
|
|
105
|
+
const goalSummary = completed.length > 0 ? `Completed ${completed.length} task(s) before auto-compact` : "Session auto-compacted";
|
|
106
|
+
lines.push("---");
|
|
107
|
+
lines.push(`session: ${sessionName}`);
|
|
108
|
+
lines.push(`date: ${dateOnly}`);
|
|
109
|
+
lines.push("status: partial");
|
|
110
|
+
lines.push("outcome: PARTIAL_PLUS");
|
|
111
|
+
lines.push("---");
|
|
112
|
+
lines.push("");
|
|
113
|
+
lines.push(`goal: ${goalSummary}`);
|
|
114
|
+
lines.push(`now: ${currentTask}`);
|
|
115
|
+
lines.push("test: # No test command captured");
|
|
116
|
+
lines.push("");
|
|
117
|
+
lines.push("done_this_session:");
|
|
118
|
+
if (completed.length > 0) {
|
|
119
|
+
completed.forEach((t) => {
|
|
120
|
+
lines.push(` - task: "${t.content.replace(/"/g, '\\"')}"`);
|
|
121
|
+
lines.push(" files: []");
|
|
122
|
+
});
|
|
123
|
+
} else {
|
|
124
|
+
lines.push(' - task: "Session started"');
|
|
125
|
+
lines.push(" files: []");
|
|
126
|
+
}
|
|
127
|
+
lines.push("");
|
|
128
|
+
lines.push("blockers:");
|
|
129
|
+
if (summary.errorsEncountered.length > 0) {
|
|
130
|
+
summary.errorsEncountered.slice(0, 3).forEach((e) => {
|
|
131
|
+
const safeError = e.replace(/"/g, '\\"').substring(0, 100);
|
|
132
|
+
lines.push(` - "${safeError}"`);
|
|
133
|
+
});
|
|
134
|
+
} else {
|
|
135
|
+
lines.push(" []");
|
|
136
|
+
}
|
|
137
|
+
lines.push("");
|
|
138
|
+
lines.push("questions:");
|
|
139
|
+
if (pending.length > 0) {
|
|
140
|
+
pending.slice(0, 3).forEach((t) => {
|
|
141
|
+
lines.push(` - "Resume: ${t.content.replace(/"/g, '\\"')}"`);
|
|
142
|
+
});
|
|
143
|
+
} else {
|
|
144
|
+
lines.push(" []");
|
|
145
|
+
}
|
|
146
|
+
lines.push("");
|
|
147
|
+
lines.push("decisions:");
|
|
148
|
+
lines.push(' - auto_compact: "Context limit reached, auto-compacted"');
|
|
149
|
+
lines.push("");
|
|
150
|
+
lines.push("findings:");
|
|
151
|
+
lines.push(` - tool_calls: "${summary.recentToolCalls.length} recent tool calls"`);
|
|
152
|
+
lines.push(` - files_modified: "${summary.filesModified.length} files changed"`);
|
|
153
|
+
lines.push("");
|
|
154
|
+
lines.push("worked:");
|
|
155
|
+
const successfulTools = summary.recentToolCalls.filter((t) => t.success);
|
|
156
|
+
if (successfulTools.length > 0) {
|
|
157
|
+
lines.push(` - "${successfulTools.map((t) => t.name).join(", ")} completed successfully"`);
|
|
158
|
+
} else {
|
|
159
|
+
lines.push(" []");
|
|
160
|
+
}
|
|
161
|
+
lines.push("");
|
|
162
|
+
lines.push("failed:");
|
|
163
|
+
const failedTools = summary.recentToolCalls.filter((t) => !t.success);
|
|
164
|
+
if (failedTools.length > 0) {
|
|
165
|
+
lines.push(` - "${failedTools.map((t) => t.name).join(", ")} encountered errors"`);
|
|
166
|
+
} else {
|
|
167
|
+
lines.push(" []");
|
|
168
|
+
}
|
|
169
|
+
lines.push("");
|
|
170
|
+
lines.push("next:");
|
|
171
|
+
if (inProgress.length > 0) {
|
|
172
|
+
lines.push(` - "Continue: ${inProgress[0].content.replace(/"/g, '\\"')}"`);
|
|
173
|
+
}
|
|
174
|
+
if (pending.length > 0) {
|
|
175
|
+
pending.slice(0, 2).forEach((t) => {
|
|
176
|
+
lines.push(` - "${t.content.replace(/"/g, '\\"')}"`);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
if (inProgress.length === 0 && pending.length === 0) {
|
|
180
|
+
lines.push(' - "Review session state and continue"');
|
|
181
|
+
}
|
|
182
|
+
lines.push("");
|
|
183
|
+
lines.push("files:");
|
|
184
|
+
lines.push(" created: []");
|
|
185
|
+
lines.push(" modified:");
|
|
186
|
+
if (summary.filesModified.length > 0) {
|
|
187
|
+
summary.filesModified.slice(0, 10).forEach((f) => {
|
|
188
|
+
lines.push(` - "${f}"`);
|
|
189
|
+
});
|
|
190
|
+
} else {
|
|
191
|
+
lines.push(" []");
|
|
192
|
+
}
|
|
193
|
+
return lines.join("\n");
|
|
194
|
+
}
|
|
195
|
+
var isMainModule = import.meta.url === `file://${process.argv[1]}`;
|
|
196
|
+
if (isMainModule) {
|
|
197
|
+
const args = process.argv.slice(2);
|
|
198
|
+
if (args.length === 0) {
|
|
199
|
+
console.log("Usage: npx tsx transcript-parser.ts <transcript-path> [session-name]");
|
|
200
|
+
process.exit(1);
|
|
201
|
+
}
|
|
202
|
+
const transcriptPath = args[0];
|
|
203
|
+
const sessionName = args[1] || "test-session";
|
|
204
|
+
console.log(`Parsing transcript: ${transcriptPath}`);
|
|
205
|
+
const summary = parseTranscript(transcriptPath);
|
|
206
|
+
console.log("\n--- Summary ---");
|
|
207
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
208
|
+
console.log("\n--- Auto-Handoff ---");
|
|
209
|
+
console.log(generateAutoHandoff(summary, sessionName));
|
|
210
|
+
}
|
|
211
|
+
export {
|
|
212
|
+
generateAutoHandoff,
|
|
213
|
+
parseTranscript
|
|
214
|
+
};
|
package/install.sh
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Qualitative Research Pro installer
|
|
3
|
+
# Academic qualitative research squad for Claude Code / Codex CLI
|
|
4
|
+
# Merges ecosystem files without overwriting your existing setup
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
REPO_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
9
|
+
CLAUDE_DIR="$HOME/.claude"
|
|
10
|
+
FORCE=false
|
|
11
|
+
ADDED=0
|
|
12
|
+
SKIPPED=0
|
|
13
|
+
|
|
14
|
+
for arg in "$@"; do
|
|
15
|
+
case $arg in
|
|
16
|
+
--force) FORCE=true ;;
|
|
17
|
+
--non-interactive) NON_INTERACTIVE=true ;;
|
|
18
|
+
--help|-h)
|
|
19
|
+
echo "Usage: ./install.sh [--force] [--non-interactive]"
|
|
20
|
+
echo ""
|
|
21
|
+
echo " --force Overwrite existing files (default: skip existing)"
|
|
22
|
+
echo " --non-interactive Skip confirmation prompt"
|
|
23
|
+
echo ""
|
|
24
|
+
echo "Without --force, only NEW files are added. Your existing agents,"
|
|
25
|
+
echo "skills, hooks, and rules are preserved."
|
|
26
|
+
exit 0
|
|
27
|
+
;;
|
|
28
|
+
esac
|
|
29
|
+
done
|
|
30
|
+
|
|
31
|
+
echo "Qualitative Research Pro installer"
|
|
32
|
+
echo "========================"
|
|
33
|
+
echo ""
|
|
34
|
+
echo "Academic qualitative research squad for Claude Code"
|
|
35
|
+
echo ""
|
|
36
|
+
AGENT_COUNT=$(find "$REPO_DIR/agents" -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
|
|
37
|
+
SKILL_COUNT=$(find "$REPO_DIR/skills" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')
|
|
38
|
+
HOOK_COUNT=$(find "$REPO_DIR/hooks/src" -maxdepth 1 -name "*.ts" 2>/dev/null | wc -l | tr -d ' ')
|
|
39
|
+
RULE_COUNT=$(find "$REPO_DIR/rules" -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
|
|
40
|
+
|
|
41
|
+
echo "This will install into ~/.claude/:"
|
|
42
|
+
echo " - $AGENT_COUNT agents -> ~/.claude/agents/"
|
|
43
|
+
echo " - $SKILL_COUNT skills -> ~/.claude/skills/"
|
|
44
|
+
echo " - $HOOK_COUNT hooks -> ~/.claude/hooks/"
|
|
45
|
+
echo " - $RULE_COUNT rules -> ~/.claude/rules/"
|
|
46
|
+
echo ""
|
|
47
|
+
if [ "$FORCE" = true ]; then
|
|
48
|
+
echo "Mode: OVERWRITE (--force) — existing files will be replaced"
|
|
49
|
+
else
|
|
50
|
+
echo "Mode: MERGE (default) — existing files will be preserved"
|
|
51
|
+
fi
|
|
52
|
+
echo ""
|
|
53
|
+
|
|
54
|
+
# Check for Python
|
|
55
|
+
if command -v python3 &>/dev/null; then
|
|
56
|
+
PY_VERSION=$(python3 --version 2>/dev/null | head -1)
|
|
57
|
+
echo "Python detected: $PY_VERSION"
|
|
58
|
+
else
|
|
59
|
+
echo "WARNING: Python 3 not found. Install it for data processing utilities."
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# Check for pandoc
|
|
63
|
+
if command -v pandoc &>/dev/null; then
|
|
64
|
+
echo "pandoc detected"
|
|
65
|
+
else
|
|
66
|
+
echo "NOTE: pandoc not found. Install it: brew install pandoc"
|
|
67
|
+
fi
|
|
68
|
+
echo ""
|
|
69
|
+
|
|
70
|
+
if [ "$NON_INTERACTIVE" != true ]; then
|
|
71
|
+
read -p "Continue? (y/N) " -n 1 -r
|
|
72
|
+
echo
|
|
73
|
+
[[ $REPLY =~ ^[Yy]$ ]] || exit 0
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
if [ "$FORCE" = true ]; then
|
|
77
|
+
if [ -d "$CLAUDE_DIR/agents" ] || [ -d "$CLAUDE_DIR/skills" ]; then
|
|
78
|
+
BACKUP="$CLAUDE_DIR/backup-$(date +%Y%m%d-%H%M%S)"
|
|
79
|
+
echo "Backing up existing files to: $BACKUP"
|
|
80
|
+
mkdir -p "$BACKUP"
|
|
81
|
+
[ -d "$CLAUDE_DIR/agents" ] && cp -r "$CLAUDE_DIR/agents" "$BACKUP/"
|
|
82
|
+
[ -d "$CLAUDE_DIR/skills" ] && cp -r "$CLAUDE_DIR/skills" "$BACKUP/"
|
|
83
|
+
[ -d "$CLAUDE_DIR/hooks" ] && cp -r "$CLAUDE_DIR/hooks" "$BACKUP/"
|
|
84
|
+
[ -d "$CLAUDE_DIR/rules" ] && cp -r "$CLAUDE_DIR/rules" "$BACKUP/"
|
|
85
|
+
echo ""
|
|
86
|
+
fi
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
smart_copy_file() {
|
|
90
|
+
local src="$1"
|
|
91
|
+
local dest="$2"
|
|
92
|
+
if [ "$FORCE" = true ] || [ ! -e "$dest" ]; then
|
|
93
|
+
cp "$src" "$dest"
|
|
94
|
+
ADDED=$((ADDED + 1))
|
|
95
|
+
else
|
|
96
|
+
SKIPPED=$((SKIPPED + 1))
|
|
97
|
+
fi
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
smart_copy_dir() {
|
|
101
|
+
local src="$1"
|
|
102
|
+
local dest="$2"
|
|
103
|
+
if [ "$FORCE" = true ] || [ ! -e "$dest" ]; then
|
|
104
|
+
cp -r "$src" "$dest"
|
|
105
|
+
ADDED=$((ADDED + 1))
|
|
106
|
+
else
|
|
107
|
+
SKIPPED=$((SKIPPED + 1))
|
|
108
|
+
fi
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
echo "Installing agents..."
|
|
112
|
+
mkdir -p "$CLAUDE_DIR/agents"
|
|
113
|
+
for f in "$REPO_DIR/agents/"*.md; do
|
|
114
|
+
[ -f "$f" ] || continue
|
|
115
|
+
name=$(basename "$f")
|
|
116
|
+
smart_copy_file "$f" "$CLAUDE_DIR/agents/$name"
|
|
117
|
+
done
|
|
118
|
+
|
|
119
|
+
echo "Installing skills..."
|
|
120
|
+
mkdir -p "$CLAUDE_DIR/skills"
|
|
121
|
+
for d in "$REPO_DIR/skills/"*/; do
|
|
122
|
+
name=$(basename "$d")
|
|
123
|
+
[ "$name" = "*" ] && continue
|
|
124
|
+
smart_copy_dir "$d" "$CLAUDE_DIR/skills/$name"
|
|
125
|
+
done
|
|
126
|
+
|
|
127
|
+
echo "Installing hooks..."
|
|
128
|
+
mkdir -p "$CLAUDE_DIR/hooks/dist"
|
|
129
|
+
mkdir -p "$CLAUDE_DIR/hooks/src/shared"
|
|
130
|
+
for f in "$REPO_DIR/hooks/dist/"*.mjs; do
|
|
131
|
+
[ -f "$f" ] || continue
|
|
132
|
+
name=$(basename "$f")
|
|
133
|
+
smart_copy_file "$f" "$CLAUDE_DIR/hooks/dist/$name"
|
|
134
|
+
done
|
|
135
|
+
for f in "$REPO_DIR/hooks/src/"*.ts; do
|
|
136
|
+
[ -f "$f" ] || continue
|
|
137
|
+
name=$(basename "$f")
|
|
138
|
+
smart_copy_file "$f" "$CLAUDE_DIR/hooks/src/$name"
|
|
139
|
+
done
|
|
140
|
+
for f in "$REPO_DIR/hooks/src/shared/"*.ts; do
|
|
141
|
+
[ -f "$f" ] || continue
|
|
142
|
+
name=$(basename "$f")
|
|
143
|
+
smart_copy_file "$f" "$CLAUDE_DIR/hooks/src/shared/$name"
|
|
144
|
+
done
|
|
145
|
+
[ -f "$REPO_DIR/hooks/package.json" ] && cp "$REPO_DIR/hooks/package.json" "$CLAUDE_DIR/hooks/package.json"
|
|
146
|
+
[ -f "$REPO_DIR/hooks/tsconfig.json" ] && cp "$REPO_DIR/hooks/tsconfig.json" "$CLAUDE_DIR/hooks/tsconfig.json"
|
|
147
|
+
HOOK_COUNT=$(ls "$CLAUDE_DIR/hooks/dist/"*.mjs 2>/dev/null | wc -l | tr -d ' ')
|
|
148
|
+
|
|
149
|
+
echo "Installing rules..."
|
|
150
|
+
mkdir -p "$CLAUDE_DIR/rules"
|
|
151
|
+
for f in "$REPO_DIR/rules/"*.md; do
|
|
152
|
+
[ -f "$f" ] || continue
|
|
153
|
+
name=$(basename "$f")
|
|
154
|
+
smart_copy_file "$f" "$CLAUDE_DIR/rules/$name"
|
|
155
|
+
done
|
|
156
|
+
|
|
157
|
+
echo "Installing scripts..."
|
|
158
|
+
if [ -d "$REPO_DIR/scripts" ]; then
|
|
159
|
+
mkdir -p "$CLAUDE_DIR/scripts"
|
|
160
|
+
for f in "$REPO_DIR/scripts/"*; do
|
|
161
|
+
[ -f "$f" ] || continue
|
|
162
|
+
name=$(basename "$f")
|
|
163
|
+
smart_copy_file "$f" "$CLAUDE_DIR/scripts/$name"
|
|
164
|
+
done
|
|
165
|
+
fi
|
|
166
|
+
|
|
167
|
+
if [ -d "$REPO_DIR/.github/workflows" ]; then
|
|
168
|
+
echo "Installing GitHub workflow templates..."
|
|
169
|
+
mkdir -p "$CLAUDE_DIR/.github/workflows"
|
|
170
|
+
for f in "$REPO_DIR/.github/workflows/"claude-*.yml; do
|
|
171
|
+
[ -f "$f" ] || continue
|
|
172
|
+
name=$(basename "$f")
|
|
173
|
+
smart_copy_file "$f" "$CLAUDE_DIR/.github/workflows/$name"
|
|
174
|
+
done
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
echo ""
|
|
178
|
+
echo "Installation complete!"
|
|
179
|
+
echo " Added: $ADDED files"
|
|
180
|
+
echo " Skipped: $SKIPPED files (already existed)"
|
|
181
|
+
echo ""
|
|
182
|
+
echo " Agents: $(ls "$CLAUDE_DIR/agents/"*.md 2>/dev/null | wc -l | tr -d ' ')"
|
|
183
|
+
echo " Skills: $(find "$CLAUDE_DIR/skills/" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')"
|
|
184
|
+
echo " Hooks: ${HOOK_COUNT:-$(ls "$CLAUDE_DIR/hooks/dist/"*.mjs 2>/dev/null | wc -l | tr -d ' ')}"
|
|
185
|
+
echo " Rules: $(ls "$CLAUDE_DIR/rules/"*.md 2>/dev/null | wc -l | tr -d ' ')"
|
|
186
|
+
echo ""
|
|
187
|
+
if [ $SKIPPED -gt 0 ]; then
|
|
188
|
+
echo "Tip: Use ./install.sh --force to overwrite existing files."
|
|
189
|
+
fi
|
|
190
|
+
echo ""
|
|
191
|
+
echo "Recommended tools for Qualitative Research Pro:"
|
|
192
|
+
echo " - Zotero: https://www.zotero.org/"
|
|
193
|
+
echo " - pandoc: brew install pandoc"
|
|
194
|
+
echo " - Python 3.10+: for data processing utilities"
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "qualitative-research-pro",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Academic qualitative research squad for grounded theory, qualitative analysis, academic writing, and research methodology",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"qualitative-research-pro": "./bin/cli.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"agents/",
|
|
11
|
+
"skills/",
|
|
12
|
+
"hooks/dist/",
|
|
13
|
+
"hooks/hooks.json",
|
|
14
|
+
"rules/",
|
|
15
|
+
"plugin.json",
|
|
16
|
+
"bin/",
|
|
17
|
+
"install.sh",
|
|
18
|
+
"CLAUDE.md",
|
|
19
|
+
"AGENTS.md"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"grounded-theory",
|
|
23
|
+
"qualitative-research",
|
|
24
|
+
"academic-research",
|
|
25
|
+
"glaser",
|
|
26
|
+
"coding",
|
|
27
|
+
"memoing",
|
|
28
|
+
"methodology",
|
|
29
|
+
"claude-code",
|
|
30
|
+
"ai-agents",
|
|
31
|
+
"research-methods"
|
|
32
|
+
],
|
|
33
|
+
"author": "ccashwell (https://github.com/ccashwell)",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/ccashwell/qualitative-research-pro.git"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.com/ccashwell/qualitative-research-pro#readme",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/ccashwell/qualitative-research-pro/issues"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18"
|
|
45
|
+
}
|
|
46
|
+
}
|
package/plugin.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "qualitative-research-pro",
|
|
3
|
+
"description": "Academic qualitative research squad for grounded theory analysis, qualitative methodology, academic writing, and research ethics with Claude Code",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "ccashwell",
|
|
7
|
+
"url": "https://github.com/ccashwell"
|
|
8
|
+
},
|
|
9
|
+
"repository": "https://github.com/ccashwell/qualitative-research-pro",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"grounded-theory",
|
|
13
|
+
"qualitative-research",
|
|
14
|
+
"academic-research",
|
|
15
|
+
"glaser",
|
|
16
|
+
"methodology",
|
|
17
|
+
"claude-code"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Academic Writing Style (Qualitative Research)
|
|
2
|
+
|
|
3
|
+
Use this rule when drafting manuscripts, dissertations, memos-for-publication, or research communications.
|
|
4
|
+
|
|
5
|
+
## Voice and Hedging
|
|
6
|
+
|
|
7
|
+
- Prefer **active voice** for clarity (“We analyzed…” / “The analysis shows…”). Use passive sparingly for standard methods or when the actor is irrelevant.
|
|
8
|
+
- Hedge interpretive claims appropriately: “suggests,” “indicates,” “may,” “appears to,” paired with evidence.
|
|
9
|
+
- Avoid overstated universals (“always,” “proves”) unless design supports them.
|
|
10
|
+
|
|
11
|
+
## APA 7th Edition Defaults
|
|
12
|
+
|
|
13
|
+
- Default to **APA 7th** unless a journal or program specifies otherwise.
|
|
14
|
+
- Use author–date in-text citations and a corresponding reference list.
|
|
15
|
+
- Follow APA heading levels, seriation, and bias-free language guidance.
|
|
16
|
+
|
|
17
|
+
## Paragraph Structure and Flow
|
|
18
|
+
|
|
19
|
+
- One main idea per paragraph; opening sentence states the claim or move.
|
|
20
|
+
- Support with evidence or logical development; close with a transition or implication.
|
|
21
|
+
- Use **transition words** purposefully (however, therefore, moreover, in contrast, consequently) to signal relationships.
|
|
22
|
+
|
|
23
|
+
## First Person in Qualitative Work
|
|
24
|
+
|
|
25
|
+
- First person is acceptable for researcher actions, positionality, and method narration when consistent with venue norms.
|
|
26
|
+
- Maintain analytic focus: the researcher’s voice frames; participants’ voices illustrate.
|
|
27
|
+
|
|
28
|
+
## Participant Voice and Analysis
|
|
29
|
+
|
|
30
|
+
- Present verbatim or lightly edited excerpts in block quotes with clear attribution (pseudonym, role if relevant).
|
|
31
|
+
- Follow each excerpt with **analytical commentary** that interprets significance; avoid “data dumps.”
|
|
32
|
+
- Balance empathy with analytic distance; name categories and relationships explicitly.
|
|
33
|
+
|
|
34
|
+
## Jargon and Accessibility
|
|
35
|
+
|
|
36
|
+
- Define specialized terms on first use; prefer precise ordinary language when it serves readers.
|
|
37
|
+
- Reserve theory-laden labels for concepts earned through analysis, not imported labels without justification.
|
|
38
|
+
|
|
39
|
+
## Logical Flow
|
|
40
|
+
|
|
41
|
+
- Move from concrete evidence to abstract claims; signpost structure in introductions and discussions.
|
|
42
|
+
- Align discussion claims with findings sections; flag limitations without undermining transparent interpretation.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Citation Standards (APA 7 & Chicago)
|
|
2
|
+
|
|
3
|
+
Use this rule for in-text citations, reference lists, and methodology-heavy qualitative manuscripts.
|
|
4
|
+
|
|
5
|
+
## APA 7th Edition (Default)
|
|
6
|
+
|
|
7
|
+
### In-Text Citations
|
|
8
|
+
|
|
9
|
+
- **Narrative**: Glaser (1978) argued that…
|
|
10
|
+
- **Parenthetical**: (Glaser, 1978, p. 45) for direct quotes with page numbers when available.
|
|
11
|
+
- For **paraphrases**, include page numbers when quoting closely or when pagination aids verification.
|
|
12
|
+
- **Et al.**: For works with three or more authors, use first author + “et al.” in every citation (APA 7).
|
|
13
|
+
|
|
14
|
+
### Reference List
|
|
15
|
+
|
|
16
|
+
- Alphabetize; hanging indent; include DOI or URL when available, formatted per APA.
|
|
17
|
+
- **DOIs**: Prefer `https://doi.org/10.xxxx/xxxxx` in stable form.
|
|
18
|
+
- Match every in-text citation to a reference entry; verify years and editions.
|
|
19
|
+
|
|
20
|
+
## Chicago (Notes-Bibliography or Author-Date)
|
|
21
|
+
|
|
22
|
+
- Use when discipline or venue requires (e.g., some humanities fields).
|
|
23
|
+
- **Notes**: Full note first occurrence; shortened notes thereafter; bibliography with full details.
|
|
24
|
+
- **Author-date**: Parallel to APA in spirit but follow Chicago spacing and punctuation rules.
|
|
25
|
+
|
|
26
|
+
## Canonical Grounded Theory Sources (Examples for Reference Lists)
|
|
27
|
+
|
|
28
|
+
- Glaser, B. G. (1978). *Theoretical sensitivity*. Sociology Press.
|
|
29
|
+
- Glaser, B. G. (1992). *Basics of grounded theory analysis*. Sociology Press.
|
|
30
|
+
- Glaser, B. G. (1998). *Doing grounded theory: Issues and discussions*. Sociology Press.
|
|
31
|
+
- Glaser, B. G., & Strauss, A. L. (1967). *The discovery of grounded theory*. Aldine.
|
|
32
|
+
|
|
33
|
+
Always verify pagination, city, and publisher requirements of your style manual and publisher.
|
|
34
|
+
|
|
35
|
+
## Unpublished Data and Field Materials
|
|
36
|
+
|
|
37
|
+
- Cite participant data **only** as allowed by consent and IRB; typically avoid identifiable archives in references.
|
|
38
|
+
- Use generic descriptors in methods (“interview data, 2024–2026”) unless a registered repository is approved.
|
|
39
|
+
|
|
40
|
+
## Secondary Sources
|
|
41
|
+
|
|
42
|
+
- Prefer **primary** sources; when citing a source quoted in another work, credit both per APA secondary source rules.
|
|
43
|
+
- In qualitative writing, trace original methodological claims to original texts when possible.
|
|
44
|
+
|
|
45
|
+
## Quality Checks
|
|
46
|
+
|
|
47
|
+
- [ ] DOIs/URLs resolve; [ ] edition/year correct for seminal texts; [ ] direct quotes have locations; [ ] unpublished items handled per ethics approval.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Current Methodological State (2026)
|
|
2
|
+
|
|
3
|
+
Use this rule for tool selection, AI-assisted workflows, and situating grounded theory within contemporary qualitative debates.
|
|
4
|
+
|
|
5
|
+
## CAQDAS Landscape (Circa 2026)
|
|
6
|
+
|
|
7
|
+
Major platforms continue to evolve on collaboration, cloud deployment, and mixed-methods integration:
|
|
8
|
+
|
|
9
|
+
- **NVivo 15** — Widely used in applied and team projects; strong query and coding tools; verify institutional license and data residency.
|
|
10
|
+
- **ATLAS.ti 24** — Visual/network-friendly; check export options for long-term archival needs.
|
|
11
|
+
- **MAXQDA 2024** — Mixed-methods and survey linkage features; confirm encryption and team workflows.
|
|
12
|
+
- **Dedoose** — Browser-based collaboration; suitable for distributed teams; validate security posture for sensitive data.
|
|
13
|
+
|
|
14
|
+
Choose based on **IRB constraints**, **encryption**, **audit logs**, **vendor lock-in**, and **training** available to the team.
|
|
15
|
+
|
|
16
|
+
## AI-Assisted Qualitative Analysis
|
|
17
|
+
|
|
18
|
+
- **Ethical considerations**: consent for machine processing, data processing agreements, re-identification risk in cloud APIs, and institutional AI policies.
|
|
19
|
+
- **Appropriate uses**: administrative tasks (formatting timestamps), **hypothesis generation** to be verified against data, exploratory summaries under researcher supervision.
|
|
20
|
+
- **Limitations**: synthetic “themes” without traceability, hallucinated citations, flattening of context, and weak accountability for marginalized voices.
|
|
21
|
+
- Always retain **human-led** coding, memoing, and audit trails; treat AI output as **provisional**.
|
|
22
|
+
|
|
23
|
+
## Debates in Grounded Theory and Qualitative Inquiry
|
|
24
|
+
|
|
25
|
+
- **Methodological evolution**: classic, evolved, and constructivist GT lineages; clarity about lineage reduces talking-past-one-another in review.
|
|
26
|
+
- **Digital ethnography**: platform norms, trace data ethics, and rapid context change challenge static field boundaries.
|
|
27
|
+
- **Visual GT**: images and multimodal data as empirical materials; require explicit semiotic and ethical handling.
|
|
28
|
+
|
|
29
|
+
## Key Recent Publications (Illustrative Directions)
|
|
30
|
+
|
|
31
|
+
- Follow current issues of *Qualitative Inquiry*, *Qualitative Research*, *Forum: Qualitative Social Research*, and flagship handbooks in your discipline for **up-to-date** exemplars and controversies—verify citations at write time.
|
|
32
|
+
|
|
33
|
+
## APA and Open Science
|
|
34
|
+
|
|
35
|
+
- **APA 7th** remains the default in much social and behavioral science; confirm journal supplements for qualitative reporting (e.g., exemplar tables, positionality).
|
|
36
|
+
- **Open science in qualitative work**: preregistration where feasible, registered reports in some venues, **de-identified** data and excerpt sharing when ethical; opaque sharing when not.
|
|
37
|
+
|
|
38
|
+
## Practical Takeaway
|
|
39
|
+
|
|
40
|
+
Pair tool choices and AI use with **ethics approval**, **documentation**, and **transparent** statements of analytic lineage—software and models change; accountable process endures.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Qualitative Data Handling
|
|
2
|
+
|
|
3
|
+
Use this rule for organizing, securing, anonymizing, and retaining qualitative materials across the research lifecycle.
|
|
4
|
+
|
|
5
|
+
## File Naming Conventions
|
|
6
|
+
|
|
7
|
+
- Use consistent, machine-safe names: `YYYY-MM-DD_pseudonym_session01_transcript-v2.docx` (adjust to IRB constraints).
|
|
8
|
+
- Avoid real names, initials tied to identity, or geotags in filenames and metadata.
|
|
9
|
+
- Version transcripts and coded exports with `_v#` or semantic versioning notes in a change log.
|
|
10
|
+
|
|
11
|
+
## Directory Structure (Example)
|
|
12
|
+
|
|
13
|
+
- `01_admin/` — IRB, consent templates (encrypted), recruitment logs (de-identified).
|
|
14
|
+
- `02_raw/` — audio/video (encrypted); restricted access.
|
|
15
|
+
- `03_processed/` — transcripts, anonymized field notes, cleaned documents.
|
|
16
|
+
- `04_analysis/` — exports from CAQDAS, codebooks, memo banks.
|
|
17
|
+
- `05_outputs/` — figures, models, publication-ready excerpts (reviewed for disclosure risk).
|
|
18
|
+
|
|
19
|
+
## Anonymization Procedures
|
|
20
|
+
|
|
21
|
+
- Replace direct identifiers; generalize places and dates when they enable re-identification.
|
|
22
|
+
- Review quotations for **jigsaw risk** (combinations of details that identify individuals or sites).
|
|
23
|
+
- Maintain a separate, secured **re-identification key** if required for follow-up; never merge key with shared analytic files.
|
|
24
|
+
|
|
25
|
+
## Secure Storage
|
|
26
|
+
|
|
27
|
+
- Institutional secure drives or approved encrypted containers; full-disk encryption on field devices.
|
|
28
|
+
- Separate accounts for shared projects; log access where policy requires.
|
|
29
|
+
- Delete local copies of restricted files from personal devices after secure upload.
|
|
30
|
+
|
|
31
|
+
## Backup Strategy
|
|
32
|
+
|
|
33
|
+
- Follow 3-2-1 principles where permitted: three copies, two media types, one off-site **approved** backup.
|
|
34
|
+
- Test restores periodically; document backup locations and responsible parties.
|
|
35
|
+
|
|
36
|
+
## CAQDAS Tool Recommendations
|
|
37
|
+
|
|
38
|
+
- **NVivo**, **ATLAS.ti**, **MAXQDA**, **Dedoose** — choose based on collaboration needs, mixed methods, cloud policy, and institutional licenses.
|
|
39
|
+
- Export codebooks and project logs regularly in vendor-neutral formats when available.
|
|
40
|
+
|
|
41
|
+
## Retention and Destruction
|
|
42
|
+
|
|
43
|
+
- Align with IRB, funder, and legal holds; document destruction dates and methods (secure erase, shredding).
|
|
44
|
+
- Clarify whether participants consented to archiving or future reuse; honor opt-outs.
|