@zalom/plastic 1.0.0-alpha.1 → 1.0.0-alpha.2
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/package.json +1 -1
- package/scripts/install.rb +74 -25
package/package.json
CHANGED
package/scripts/install.rb
CHANGED
|
@@ -304,42 +304,78 @@ end
|
|
|
304
304
|
|
|
305
305
|
def merge_claude_hooks(settings_path)
|
|
306
306
|
settings = read_json_safe(settings_path) || {}
|
|
307
|
-
return if settings.nil?
|
|
307
|
+
return if settings.nil?
|
|
308
308
|
|
|
309
309
|
hooks = settings["hooks"] ||= {}
|
|
310
310
|
hook_dir = File.join(Dir.home, ".claude", "hooks")
|
|
311
311
|
|
|
312
|
+
purge_stale_plastic_hooks(hooks)
|
|
313
|
+
|
|
312
314
|
plastic_hooks = {
|
|
313
|
-
"SessionStart" =>
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
"
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
315
|
+
"SessionStart" => {
|
|
316
|
+
"matcher" => "",
|
|
317
|
+
"hooks" => [
|
|
318
|
+
{ "type" => "command", "command" => "#{hook_dir}/plastic-session-start", "statusMessage" => "Loading Plastic context..." },
|
|
319
|
+
{ "type" => "command", "command" => "#{hook_dir}/plastic-check-update", "statusMessage" => "" },
|
|
320
|
+
],
|
|
321
|
+
},
|
|
322
|
+
"PreCompact" => {
|
|
323
|
+
"matcher" => "",
|
|
324
|
+
"hooks" => [
|
|
325
|
+
{ "type" => "command", "command" => "#{hook_dir}/plastic-savepoint", "statusMessage" => "Saving Plastic intent state..." },
|
|
326
|
+
],
|
|
327
|
+
},
|
|
328
|
+
"PostToolUse" => {
|
|
329
|
+
"matcher" => "Write|Edit",
|
|
330
|
+
"hooks" => [
|
|
331
|
+
{ "type" => "command", "command" => "#{hook_dir}/plastic-gate-check", "statusMessage" => "Checking lifecycle gates..." },
|
|
332
|
+
],
|
|
333
|
+
},
|
|
334
|
+
"UserPromptSubmit" => {
|
|
335
|
+
"matcher" => "",
|
|
336
|
+
"hooks" => [
|
|
337
|
+
{ "type" => "command", "command" => "#{hook_dir}/plastic-continue", "statusMessage" => "Checking for continue..." },
|
|
338
|
+
{ "type" => "command", "command" => "#{hook_dir}/plastic-future-intent-check", "statusMessage" => "Checking future intents..." },
|
|
339
|
+
],
|
|
340
|
+
},
|
|
330
341
|
}
|
|
331
342
|
|
|
332
|
-
plastic_hooks.each do |event,
|
|
343
|
+
plastic_hooks.each do |event, group|
|
|
333
344
|
hooks[event] ||= []
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
345
|
+
existing = hooks[event].find { |g| g.is_a?(Hash) && g["hooks"].is_a?(Array) && g["hooks"].any? { |h| h["command"].to_s.include?("plastic-") } }
|
|
346
|
+
|
|
347
|
+
if existing
|
|
348
|
+
existing["matcher"] = group["matcher"]
|
|
349
|
+
existing["hooks"] = group["hooks"]
|
|
350
|
+
else
|
|
351
|
+
hooks[event] << group
|
|
337
352
|
end
|
|
338
353
|
end
|
|
339
354
|
|
|
355
|
+
settings["statusLine"] = { "type" => "command", "command" => "#{hook_dir}/plastic-statusline" }
|
|
356
|
+
|
|
340
357
|
write_json_atomic(settings_path, settings)
|
|
341
358
|
end
|
|
342
359
|
|
|
360
|
+
def purge_stale_plastic_hooks(hooks)
|
|
361
|
+
stale = ->(cmd) { cmd.to_s.match?(/ruby\s+.*plastic-/) || cmd.to_s.match?(/plastic-[a-z-]+\.rb/) }
|
|
362
|
+
|
|
363
|
+
hooks.each do |event, groups|
|
|
364
|
+
next unless groups.is_a?(Array)
|
|
365
|
+
|
|
366
|
+
hooks[event] = groups.map do |group|
|
|
367
|
+
if group.is_a?(Hash) && group["hooks"].is_a?(Array)
|
|
368
|
+
group["hooks"].reject! { |h| stale.call(h["command"]) }
|
|
369
|
+
group unless group["hooks"].empty?
|
|
370
|
+
elsif group.is_a?(Hash) && group["command"]
|
|
371
|
+
stale.call(group["command"]) ? nil : group
|
|
372
|
+
else
|
|
373
|
+
group
|
|
374
|
+
end
|
|
375
|
+
end.compact
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
|
|
343
379
|
# --- Uninstall ---
|
|
344
380
|
|
|
345
381
|
def handle_uninstall(agents)
|
|
@@ -403,11 +439,24 @@ def remove_claude_hooks(settings_path)
|
|
|
403
439
|
settings = read_json_safe(settings_path)
|
|
404
440
|
return unless settings && settings["hooks"]
|
|
405
441
|
|
|
406
|
-
settings["hooks"].each do |event,
|
|
407
|
-
|
|
442
|
+
settings["hooks"].each do |event, groups|
|
|
443
|
+
next unless groups.is_a?(Array)
|
|
444
|
+
|
|
445
|
+
settings["hooks"][event] = groups.map do |group|
|
|
446
|
+
if group.is_a?(Hash) && group["hooks"].is_a?(Array)
|
|
447
|
+
group["hooks"].reject! { |h| h["command"].to_s.include?("plastic-") }
|
|
448
|
+
group unless group["hooks"].empty?
|
|
449
|
+
elsif group.is_a?(Hash) && group["command"]
|
|
450
|
+
group["command"].to_s.include?("plastic-") ? nil : group
|
|
451
|
+
else
|
|
452
|
+
group
|
|
453
|
+
end
|
|
454
|
+
end.compact
|
|
408
455
|
end
|
|
409
|
-
|
|
456
|
+
|
|
457
|
+
settings["hooks"].delete_if { |_, v| v.is_a?(Array) && v.empty? }
|
|
410
458
|
settings.delete("hooks") if settings["hooks"]&.empty?
|
|
459
|
+
settings.delete("statusLine") if settings.dig("statusLine", "command").to_s.include?("plastic-")
|
|
411
460
|
|
|
412
461
|
write_json_atomic(settings_path, settings)
|
|
413
462
|
end
|