@scriptgun/workerc 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.
@@ -0,0 +1,88 @@
1
+ #!/bin/bash
2
+ # SessionStart hook: Re-inject tracker + spec context after compaction
3
+ # Fires on: compact (registered via matcher in settings.local.json)
4
+ # Output: additionalContext with tracker content, spec content, and action instructions
5
+
6
+ INPUT=$(cat)
7
+ SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty')
8
+
9
+ [ -z "$SESSION_ID" ] && exit 0
10
+
11
+ TRACKER_DIR="$(cd "$(dirname "$0")/../progress" 2>/dev/null && pwd)"
12
+ [ -z "$TRACKER_DIR" ] || [ ! -d "$TRACKER_DIR" ] && exit 0
13
+
14
+ PROJECT_DIR="$(cd "$(dirname "$0")/../.." 2>/dev/null && pwd)"
15
+
16
+ # Find this session's active tracker
17
+ MY_TRACKER=""
18
+ for t in "$TRACKER_DIR"/*.md; do
19
+ [ -f "$t" ] || continue
20
+ LINE1=$(head -1 "$t")
21
+ echo "$LINE1" | grep -q "\[DONE\]" && continue
22
+ echo "$LINE1" | grep -q "\[ABORTED\]" && continue
23
+ LINE2=$(sed -n '2p' "$t")
24
+ if echo "$LINE2" | grep -q "<!-- session: $SESSION_ID -->"; then
25
+ MY_TRACKER="$t"
26
+ break
27
+ fi
28
+ done
29
+
30
+ [ -z "$MY_TRACKER" ] && exit 0
31
+
32
+ # Read tracker
33
+ TRACKER_CONTENT=$(cat "$MY_TRACKER")
34
+ TRACKER_NAME=$(basename "$MY_TRACKER")
35
+ TRACKER_REL=".claude/progress/$TRACKER_NAME"
36
+
37
+ # Extract spec path (line 3 format: <!-- spec: path -->)
38
+ SPEC_PATH=""
39
+ SPEC_CONTENT=""
40
+ SPEC_LINE=$(sed -n '3p' "$MY_TRACKER")
41
+ if echo "$SPEC_LINE" | grep -q "<!-- spec:"; then
42
+ SPEC_PATH=$(echo "$SPEC_LINE" | sed -n 's/<!-- spec: \(.*\) -->/\1/p')
43
+ fi
44
+
45
+ if [ -n "$SPEC_PATH" ] && [ "$SPEC_PATH" != "None" ]; then
46
+ FULL_SPEC="$PROJECT_DIR/$SPEC_PATH"
47
+ if [ -f "$FULL_SPEC" ]; then
48
+ SPEC_CONTENT=$(cat "$FULL_SPEC")
49
+ fi
50
+ fi
51
+
52
+ # Count completed entries to show progress
53
+ DONE_COUNT=$(grep -c '^\- \[x\]' "$MY_TRACKER" 2>/dev/null || echo "0")
54
+
55
+ # Build context
56
+ CONTEXT="# SESSION CONTEXT RESTORED (post-compaction)
57
+
58
+ You are CONTINUING an existing work session. You are NOT starting fresh.
59
+ Your session ID: $SESSION_ID
60
+
61
+ ## Active Progress: $TRACKER_REL ($DONE_COUNT entries)
62
+ $TRACKER_CONTENT
63
+
64
+ ## REQUIRED: After reading this, immediately:
65
+ 1. Re-read your progress file: Read file $PROJECT_DIR/$TRACKER_REL"
66
+
67
+ if [ -n "$SPEC_PATH" ] && [ "$SPEC_PATH" != "None" ]; then
68
+ CONTEXT="$CONTEXT
69
+ 2. Re-read your spec: Read file $PROJECT_DIR/$SPEC_PATH"
70
+ fi
71
+
72
+ CONTEXT="$CONTEXT
73
+ 3. Review the last few log entries to understand where you left off
74
+ 4. Re-read files listed in ## Files to rebuild code context
75
+ 5. Continue working — do NOT ask the user what to do next unless genuinely stuck
76
+
77
+ ## Hooks still active:
78
+ {{ACTIVE_HOOKS}}"
79
+
80
+ if [ -n "$SPEC_CONTENT" ]; then
81
+ CONTEXT="$CONTEXT
82
+
83
+ ## Spec: $SPEC_PATH
84
+ $SPEC_CONTENT"
85
+ fi
86
+
87
+ jq -n --arg ctx "$CONTEXT" '{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":$ctx}}'
88
+ exit 0
@@ -0,0 +1,16 @@
1
+ export interface WriteOptions {
2
+ projectDir: string;
3
+ enableLint: boolean;
4
+ lintCommand: string;
5
+ lintExtensions: string;
6
+ lintHookFilename: string;
7
+ enableTypes: boolean;
8
+ typeCommand: string;
9
+ typeExtensions: string;
10
+ typesHookFilename: string;
11
+ activeHooksDescription: string;
12
+ }
13
+ export declare function writeFiles(options: WriteOptions): {
14
+ commands: string[];
15
+ hooks: string[];
16
+ };
@@ -0,0 +1,78 @@
1
+ import { chmodSync, cpSync, existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync, } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ function getTemplateDir() {
5
+ const thisFile = fileURLToPath(import.meta.url);
6
+ /* In dist/write-files.js → templates are in dist/templates/ */
7
+ const dir = join(thisFile, "..", "templates");
8
+ if (existsSync(dir))
9
+ return dir;
10
+ /* Fallback: src layout (dev) */
11
+ return join(thisFile, "..", "..", "src", "templates");
12
+ }
13
+ function ensureDir(dir) {
14
+ if (!existsSync(dir)) {
15
+ mkdirSync(dir, { recursive: true });
16
+ }
17
+ }
18
+ function renderTemplate(content, vars) {
19
+ let result = content;
20
+ for (const [key, value] of Object.entries(vars)) {
21
+ result = result.replaceAll(`{{{${key}}}}`, value);
22
+ result = result.replaceAll(`{{${key}}}`, value);
23
+ }
24
+ return result;
25
+ }
26
+ export function writeFiles(options) {
27
+ const templateDir = getTemplateDir();
28
+ const claudeDir = join(options.projectDir, ".claude");
29
+ const commandsTarget = join(claudeDir, "commands", "workerc");
30
+ const hooksTarget = join(claudeDir, "hooks");
31
+ const progressDir = join(claudeDir, "progress");
32
+ ensureDir(commandsTarget);
33
+ ensureDir(hooksTarget);
34
+ ensureDir(progressDir);
35
+ /* Copy command templates verbatim */
36
+ const commandsSrc = join(templateDir, "commands");
37
+ const commandFiles = readdirSync(commandsSrc).filter((f) => f.endsWith(".md"));
38
+ for (const file of commandFiles) {
39
+ cpSync(join(commandsSrc, file), join(commandsTarget, file));
40
+ }
41
+ /* Copy/template hook files */
42
+ const writtenHooks = [];
43
+ /* Tracker — verbatim copy */
44
+ cpSync(join(templateDir, "hooks", "post-edit-tracker.sh"), join(hooksTarget, "post-edit-tracker.sh"));
45
+ chmodSync(join(hooksTarget, "post-edit-tracker.sh"), 0o755);
46
+ writtenHooks.push("post-edit-tracker.sh");
47
+ /* Session start compact — template {{ACTIVE_HOOKS}} */
48
+ const compactSrc = readFileSync(join(templateDir, "hooks", "session-start-compact.sh"), "utf-8");
49
+ const compactRendered = renderTemplate(compactSrc, {
50
+ ACTIVE_HOOKS: options.activeHooksDescription,
51
+ });
52
+ writeFileSync(join(hooksTarget, "session-start-compact.sh"), compactRendered);
53
+ chmodSync(join(hooksTarget, "session-start-compact.sh"), 0o755);
54
+ writtenHooks.push("session-start-compact.sh");
55
+ /* Lint hook — optional, from template */
56
+ if (options.enableLint) {
57
+ const lintTmpl = readFileSync(join(templateDir, "hooks", "post-edit-lint.sh.tmpl"), "utf-8");
58
+ const lintRendered = renderTemplate(lintTmpl, {
59
+ LINT_COMMAND: options.lintCommand,
60
+ EXTENSIONS: options.lintExtensions,
61
+ });
62
+ writeFileSync(join(hooksTarget, options.lintHookFilename), lintRendered);
63
+ chmodSync(join(hooksTarget, options.lintHookFilename), 0o755);
64
+ writtenHooks.push(options.lintHookFilename);
65
+ }
66
+ /* Types hook — optional, from template */
67
+ if (options.enableTypes) {
68
+ const typesTmpl = readFileSync(join(templateDir, "hooks", "post-edit-types.sh.tmpl"), "utf-8");
69
+ const typesRendered = renderTemplate(typesTmpl, {
70
+ TYPE_COMMAND: options.typeCommand,
71
+ EXTENSIONS: options.typeExtensions,
72
+ });
73
+ writeFileSync(join(hooksTarget, options.typesHookFilename), typesRendered);
74
+ chmodSync(join(hooksTarget, options.typesHookFilename), 0o755);
75
+ writtenHooks.push(options.typesHookFilename);
76
+ }
77
+ return { commands: commandFiles, hooks: writtenHooks };
78
+ }
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@scriptgun/workerc",
3
+ "version": "0.1.0",
4
+ "description": "Claude Code session management CLI — commands, hooks, and progress tracking",
5
+ "type": "module",
6
+ "bin": {
7
+ "workerc": "./dist/bin.js"
8
+ },
9
+ "main": "./dist/init.js",
10
+ "types": "./dist/init.d.ts",
11
+ "files": [
12
+ "dist",
13
+ "README.md"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc && cp -r src/templates dist/templates",
17
+ "type:check": "tsc --noEmit"
18
+ },
19
+ "keywords": [
20
+ "claude",
21
+ "claude-code",
22
+ "session",
23
+ "hooks",
24
+ "cli",
25
+ "workerc"
26
+ ],
27
+ "license": "MIT",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/lovrozagar/workerc"
31
+ },
32
+ "dependencies": {
33
+ "@clack/prompts": "1.0.0"
34
+ },
35
+ "devDependencies": {
36
+ "typescript": "^5.9.3"
37
+ }
38
+ }