@devness/useai-cli 0.4.12 → 0.4.14

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.
Files changed (2) hide show
  1. package/dist/index.js +62 -13
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -30,7 +30,7 @@ var SYSTEMD_SERVICE_PATH = join(homedir(), ".config", "systemd", "user", "useai-
30
30
  var WINDOWS_STARTUP_SCRIPT_PATH = join(process.env["APPDATA"] ?? join(homedir(), "AppData", "Roaming"), "Microsoft", "Windows", "Start Menu", "Programs", "Startup", "useai-daemon.vbs");
31
31
 
32
32
  // ../shared/dist/constants/version.js
33
- var VERSION = "0.4.12";
33
+ var VERSION = "0.4.14";
34
34
 
35
35
  // ../shared/dist/constants/defaults.js
36
36
  var DEFAULT_CONFIG = {
@@ -4881,6 +4881,7 @@ import { existsSync as existsSync7, readFileSync as readFileSync3, writeFileSync
4881
4881
  import { join as join3 } from "path";
4882
4882
  import { homedir as homedir3 } from "os";
4883
4883
  var STOP_GUARD_PATH = join3(USEAI_HOOKS_DIR, "stop-guard.js");
4884
+ var PROMPT_GUARD_PATH = join3(USEAI_HOOKS_DIR, "prompt-guard.js");
4884
4885
  var CLAUDE_SETTINGS_PATH = join3(homedir3(), ".claude", "settings.json");
4885
4886
  var STOP_GUARD_SCRIPT = `#!/usr/bin/env node
4886
4887
  'use strict';
@@ -4898,17 +4899,35 @@ process.stdin.on('end', () => {
4898
4899
  var starts = (transcript.match(/useai_session_start/g) || []).length;
4899
4900
  if (starts === 0) process.exit(0);
4900
4901
  var ends = (transcript.match(/useai_session_end/g) || []).length;
4901
- if (starts > ends) {
4902
- process.stdout.write(JSON.stringify({
4903
- decision: 'block',
4904
- reason: 'Before ending, call useai_session_end with milestones (generic descriptions of accomplishments), languages used, and files_touched_count.'
4905
- }));
4906
- } else {
4907
- process.stdout.write(JSON.stringify({
4908
- decision: 'block',
4909
- reason: 'You did work without UseAI tracking. Call useai_session_start first, then useai_session_end with milestones (generic descriptions of accomplishments), languages used, and files_touched_count.'
4910
- }));
4911
- }
4902
+ if (ends >= starts) process.exit(0);
4903
+ process.stdout.write(JSON.stringify({
4904
+ decision: 'block',
4905
+ reason: 'Before ending, call useai_session_end with milestones (generic descriptions of accomplishments), languages used, and files_touched_count.'
4906
+ }));
4907
+ } catch { process.exit(0); }
4908
+ });
4909
+ `;
4910
+ var PROMPT_GUARD_SCRIPT = `#!/usr/bin/env node
4911
+ 'use strict';
4912
+ const { readFileSync } = require('node:fs');
4913
+ let input = '';
4914
+ process.stdin.setEncoding('utf-8');
4915
+ process.stdin.on('data', chunk => input += chunk);
4916
+ process.stdin.on('end', () => {
4917
+ try {
4918
+ const hook = JSON.parse(input);
4919
+ if (!hook.transcript_path) process.exit(0);
4920
+ let transcript;
4921
+ try { transcript = readFileSync(hook.transcript_path, 'utf-8'); } catch { process.exit(0); }
4922
+ var starts = (transcript.match(/useai_session_start/g) || []).length;
4923
+ var ends = (transcript.match(/useai_session_end/g) || []).length;
4924
+ if (starts > ends) process.exit(0);
4925
+ process.stdout.write(JSON.stringify({
4926
+ hookSpecificOutput: {
4927
+ hookEventName: 'UserPromptSubmit',
4928
+ additionalContext: 'UseAI: Call useai_session_start with the appropriate task_type before doing any work.'
4929
+ }
4930
+ }));
4912
4931
  } catch { process.exit(0); }
4913
4932
  });
4914
4933
  `;
@@ -4928,15 +4947,32 @@ function writeSettings(settings) {
4928
4947
  function installClaudeCodeHooks() {
4929
4948
  mkdirSync3(USEAI_HOOKS_DIR, { recursive: true });
4930
4949
  writeFileSync3(STOP_GUARD_PATH, STOP_GUARD_SCRIPT);
4950
+ writeFileSync3(PROMPT_GUARD_PATH, PROMPT_GUARD_SCRIPT);
4931
4951
  try {
4932
4952
  chmodSync(STOP_GUARD_PATH, "755");
4933
4953
  } catch {
4934
4954
  }
4955
+ try {
4956
+ chmodSync(PROMPT_GUARD_PATH, "755");
4957
+ } catch {
4958
+ }
4935
4959
  const settings = readSettings();
4936
4960
  const hooks = settings["hooks"] ?? {};
4961
+ const promptCmd = `node "${PROMPT_GUARD_PATH}"`;
4937
4962
  const stopCmd = `node "${STOP_GUARD_PATH}"`;
4938
4963
  const sealCmd = `curl -sf -X POST http://127.0.0.1:${DAEMON_PORT}/api/seal-active --max-time 3 2>/dev/null || true`;
4939
4964
  let changed = false;
4965
+ if (!hooks["UserPromptSubmit"])
4966
+ hooks["UserPromptSubmit"] = [];
4967
+ const promptArr = hooks["UserPromptSubmit"];
4968
+ const hasPrompt = promptArr.some((g) => {
4969
+ const inner = g["hooks"];
4970
+ return inner?.some((h) => h["command"]?.includes("prompt-guard"));
4971
+ });
4972
+ if (!hasPrompt) {
4973
+ promptArr.push({ hooks: [{ type: "command", command: promptCmd, timeout: 10 }] });
4974
+ changed = true;
4975
+ }
4940
4976
  if (!hooks["Stop"])
4941
4977
  hooks["Stop"] = [];
4942
4978
  const stopArr = hooks["Stop"];
@@ -4969,6 +5005,14 @@ function removeClaudeCodeHooks() {
4969
5005
  const settings = readSettings();
4970
5006
  const hooks = settings["hooks"];
4971
5007
  if (hooks) {
5008
+ if (hooks["UserPromptSubmit"]) {
5009
+ hooks["UserPromptSubmit"] = hooks["UserPromptSubmit"].filter((g) => {
5010
+ const inner = g["hooks"];
5011
+ return !inner?.some((h) => h["command"]?.includes("prompt-guard"));
5012
+ });
5013
+ if (hooks["UserPromptSubmit"].length === 0)
5014
+ delete hooks["UserPromptSubmit"];
5015
+ }
4972
5016
  if (hooks["Stop"]) {
4973
5017
  hooks["Stop"] = hooks["Stop"].filter((g) => {
4974
5018
  const inner = g["hooks"];
@@ -4997,6 +5041,11 @@ function removeClaudeCodeHooks() {
4997
5041
  unlinkSync3(STOP_GUARD_PATH);
4998
5042
  } catch {
4999
5043
  }
5044
+ try {
5045
+ if (existsSync7(PROMPT_GUARD_PATH))
5046
+ unlinkSync3(PROMPT_GUARD_PATH);
5047
+ } catch {
5048
+ }
5000
5049
  }
5001
5050
 
5002
5051
  // src/services/tools.ts
@@ -5589,7 +5638,7 @@ async function daemonInstallFlow(tools, explicit) {
5589
5638
  try {
5590
5639
  const hooksInstalled = installClaudeCodeHooks();
5591
5640
  if (hooksInstalled) {
5592
- console.log(success("\u2713 Claude Code hooks installed (Stop + SessionEnd)"));
5641
+ console.log(success("\u2713 Claude Code hooks installed (UserPromptSubmit + Stop + SessionEnd)"));
5593
5642
  }
5594
5643
  } catch {
5595
5644
  console.log(chalk6.yellow(" \u26A0 Could not install Claude Code hooks"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devness/useai-cli",
3
- "version": "0.4.12",
3
+ "version": "0.4.14",
4
4
  "description": "CLI tool for useai.dev — stats, sync, publish your AI development workflow",
5
5
  "author": "nabeelkausari",
6
6
  "license": "MIT",