@scriptgun/workerc 0.1.2 → 0.2.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/dist/init.js
CHANGED
|
@@ -4,7 +4,28 @@ import { mergeSettings } from "./merge-settings.js";
|
|
|
4
4
|
import { writeFiles } from "./write-files.js";
|
|
5
5
|
export async function init(projectDir) {
|
|
6
6
|
p.intro("workerc init");
|
|
7
|
-
/* Step 1:
|
|
7
|
+
/* Step 1: Where to install settings */
|
|
8
|
+
const targetAnswer = await p.select({
|
|
9
|
+
message: "Where should hooks be configured?",
|
|
10
|
+
options: [
|
|
11
|
+
{
|
|
12
|
+
label: "Local (settings.local.json)",
|
|
13
|
+
value: "local",
|
|
14
|
+
hint: "just for you, gitignored",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
label: "Shared (settings.json)",
|
|
18
|
+
value: "shared",
|
|
19
|
+
hint: "committed, shared with team",
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
});
|
|
23
|
+
if (p.isCancel(targetAnswer)) {
|
|
24
|
+
p.cancel("Cancelled");
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
const target = targetAnswer;
|
|
28
|
+
/* Step 2: Detect tools */
|
|
8
29
|
const spinner = p.spinner();
|
|
9
30
|
spinner.start("Detecting project tools");
|
|
10
31
|
const detected = detect(projectDir);
|
|
@@ -18,7 +39,7 @@ export async function init(projectDir) {
|
|
|
18
39
|
if (!detected.linter && !detected.typeChecker) {
|
|
19
40
|
p.log.info("No linter or type checker detected");
|
|
20
41
|
}
|
|
21
|
-
/* Step
|
|
42
|
+
/* Step 3: Lint hook */
|
|
22
43
|
let enableLint = false;
|
|
23
44
|
let lintCommand = "";
|
|
24
45
|
let lintExtensions = "";
|
|
@@ -54,7 +75,7 @@ export async function init(projectDir) {
|
|
|
54
75
|
lintExtensions = extAnswer;
|
|
55
76
|
}
|
|
56
77
|
}
|
|
57
|
-
/* Step
|
|
78
|
+
/* Step 4: Type check hook */
|
|
58
79
|
let enableTypes = false;
|
|
59
80
|
let typeCommand = "";
|
|
60
81
|
let typeExtensions = "";
|
|
@@ -90,7 +111,7 @@ export async function init(projectDir) {
|
|
|
90
111
|
typeExtensions = extAnswer;
|
|
91
112
|
}
|
|
92
113
|
}
|
|
93
|
-
/* Step
|
|
114
|
+
/* Step 5: Build active hooks description for compact hook */
|
|
94
115
|
const hookDescriptions = [];
|
|
95
116
|
if (enableLint) {
|
|
96
117
|
hookDescriptions.push(`- ${lintHookFilename} (blocks on lint/format errors)`);
|
|
@@ -100,7 +121,7 @@ export async function init(projectDir) {
|
|
|
100
121
|
}
|
|
101
122
|
hookDescriptions.push("- post-edit-tracker.sh (blocks if progress not updated within 15s)");
|
|
102
123
|
const activeHooksDescription = hookDescriptions.join("\n");
|
|
103
|
-
/* Step
|
|
124
|
+
/* Step 6: Write files */
|
|
104
125
|
spinner.start("Writing files");
|
|
105
126
|
const result = writeFiles({
|
|
106
127
|
projectDir,
|
|
@@ -115,17 +136,18 @@ export async function init(projectDir) {
|
|
|
115
136
|
activeHooksDescription,
|
|
116
137
|
});
|
|
117
138
|
spinner.stop("Files written");
|
|
118
|
-
/* Step
|
|
139
|
+
/* Step 7: Merge settings */
|
|
119
140
|
spinner.start("Updating settings");
|
|
120
|
-
mergeSettings({
|
|
141
|
+
const settingsFile = mergeSettings({
|
|
121
142
|
projectDir,
|
|
143
|
+
target,
|
|
122
144
|
enableLint,
|
|
123
145
|
lintHookFilename,
|
|
124
146
|
enableTypes,
|
|
125
147
|
typesHookFilename,
|
|
126
148
|
});
|
|
127
149
|
spinner.stop("Settings updated");
|
|
128
|
-
/* Step
|
|
150
|
+
/* Step 8: Summary */
|
|
129
151
|
p.log.success("workerc installed");
|
|
130
152
|
p.log.message([
|
|
131
153
|
"",
|
|
@@ -135,7 +157,7 @@ export async function init(projectDir) {
|
|
|
135
157
|
"Hooks:",
|
|
136
158
|
...result.hooks.map((f) => ` .claude/hooks/${f}`),
|
|
137
159
|
"",
|
|
138
|
-
|
|
160
|
+
`Settings: .claude/${settingsFile}`,
|
|
139
161
|
"Progress: .claude/progress/",
|
|
140
162
|
"",
|
|
141
163
|
"Get started: run /workerc:new in Claude Code",
|
package/dist/merge-settings.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
export type SettingsTarget = "local" | "shared";
|
|
1
2
|
export interface MergeOptions {
|
|
2
3
|
projectDir: string;
|
|
4
|
+
target: SettingsTarget;
|
|
3
5
|
enableLint: boolean;
|
|
4
6
|
lintHookFilename: string;
|
|
5
7
|
enableTypes: boolean;
|
|
6
8
|
typesHookFilename: string;
|
|
7
9
|
}
|
|
8
|
-
export declare function mergeSettings(options: MergeOptions):
|
|
10
|
+
export declare function mergeSettings(options: MergeOptions): string;
|
package/dist/merge-settings.js
CHANGED
|
@@ -2,7 +2,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
/**
|
|
4
4
|
* Identifies workerc-managed hooks by checking if the command path
|
|
5
|
-
* contains
|
|
5
|
+
* contains one of our known script names.
|
|
6
6
|
*/
|
|
7
7
|
const WORKERC_HOOK_NAMES = [
|
|
8
8
|
"session-start-compact.sh",
|
|
@@ -17,7 +17,10 @@ function isWorkercGroup(group) {
|
|
|
17
17
|
return group.hooks.every(isWorkercHook);
|
|
18
18
|
}
|
|
19
19
|
export function mergeSettings(options) {
|
|
20
|
-
const
|
|
20
|
+
const filename = options.target === "shared"
|
|
21
|
+
? "settings.json"
|
|
22
|
+
: "settings.local.json";
|
|
23
|
+
const settingsPath = join(options.projectDir, ".claude", filename);
|
|
21
24
|
const settingsDir = dirname(settingsPath);
|
|
22
25
|
if (!existsSync(settingsDir)) {
|
|
23
26
|
mkdirSync(settingsDir, { recursive: true });
|
|
@@ -30,7 +33,7 @@ export function mergeSettings(options) {
|
|
|
30
33
|
if (!settings.hooks) {
|
|
31
34
|
settings.hooks = {};
|
|
32
35
|
}
|
|
33
|
-
/* SessionStart:
|
|
36
|
+
/* SessionStart: keep non-workerc hooks, append compact */
|
|
34
37
|
const existingSessionStart = (settings.hooks.SessionStart ?? []).filter((g) => !isWorkercGroup(g));
|
|
35
38
|
const compactHook = {
|
|
36
39
|
matcher: "compact",
|
|
@@ -42,7 +45,7 @@ export function mergeSettings(options) {
|
|
|
42
45
|
],
|
|
43
46
|
};
|
|
44
47
|
settings.hooks.SessionStart = [...existingSessionStart, compactHook];
|
|
45
|
-
/* PostToolUse:
|
|
48
|
+
/* PostToolUse: keep non-workerc hooks, append workerc hooks */
|
|
46
49
|
const existingPostToolUse = (settings.hooks.PostToolUse ?? []).filter((g) => !isWorkercGroup(g));
|
|
47
50
|
const newPostToolUse = [];
|
|
48
51
|
if (options.enableLint) {
|
|
@@ -79,4 +82,5 @@ export function mergeSettings(options) {
|
|
|
79
82
|
});
|
|
80
83
|
settings.hooks.PostToolUse = [...existingPostToolUse, ...newPostToolUse];
|
|
81
84
|
writeFileSync(settingsPath, JSON.stringify(settings, null, "\t") + "\n");
|
|
85
|
+
return filename;
|
|
82
86
|
}
|
|
@@ -15,13 +15,17 @@ echo "$FILE" | grep -qE '\.({{{EXTENSIONS}}})$' || exit 0
|
|
|
15
15
|
echo "$FILE" | grep -qE '/\.claude/' && exit 0
|
|
16
16
|
|
|
17
17
|
LINT_OUTPUT=$({{{LINT_COMMAND}}} "$FILE" 2>&1)
|
|
18
|
-
|
|
19
|
-
jq -n --arg reason "Lint issues in $FILE:
|
|
20
|
-
$LINT_OUTPUT
|
|
18
|
+
EXIT_CODE=$?
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
# Success or file excluded from linter config
|
|
21
|
+
if [ $EXIT_CODE -eq 0 ]; then
|
|
22
|
+
echo '{}'
|
|
23
23
|
exit 0
|
|
24
24
|
fi
|
|
25
|
+
echo "$LINT_OUTPUT" | grep -q "No files were processed" && { echo '{}'; exit 0; }
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
jq -n --arg reason "Lint issues in $FILE:
|
|
28
|
+
$LINT_OUTPUT
|
|
29
|
+
|
|
30
|
+
FIX THESE BEFORE RESPONDING." '{"decision":"block","reason":$reason}'
|
|
27
31
|
exit 0
|
|
@@ -22,9 +22,9 @@ echo "$FILE" | grep -qE '/\.claude/' && exit 0
|
|
|
22
22
|
|
|
23
23
|
TRACKER_DIR="$(cd "$(dirname "$0")/../progress" 2>/dev/null && pwd)"
|
|
24
24
|
|
|
25
|
-
# No progress dir =
|
|
25
|
+
# No progress dir = pass through
|
|
26
26
|
if [ -z "$TRACKER_DIR" ] || [ ! -d "$TRACKER_DIR" ]; then
|
|
27
|
-
|
|
27
|
+
echo '{}'
|
|
28
28
|
exit 0
|
|
29
29
|
fi
|
|
30
30
|
|
|
@@ -109,13 +109,6 @@ if [ -n "$PENDING_TRACKER" ]; then
|
|
|
109
109
|
exit 0
|
|
110
110
|
fi
|
|
111
111
|
|
|
112
|
-
# Case 3: No tracker —
|
|
113
|
-
|
|
114
|
-
if [ -n "$UNCLAIMED" ]; then
|
|
115
|
-
REASON="$REASON
|
|
116
|
-
Unclaimed trackers you could claim:$UNCLAIMED
|
|
117
|
-
|
|
118
|
-
To claim: set line 2 to <!-- session: $SESSION_ID -->"
|
|
119
|
-
fi
|
|
120
|
-
jq -n --arg reason "$REASON" '{"decision":"block","reason":$reason}'
|
|
112
|
+
# Case 3: No tracker — pass through
|
|
113
|
+
echo '{}'
|
|
121
114
|
exit 0
|