@goobits/sherpa 1.0.1

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 (55) hide show
  1. package/dist/chunk-3CILH2TO.js +387 -0
  2. package/dist/chunk-3CILH2TO.js.map +7 -0
  3. package/dist/chunk-5NF3BSD6.js +512 -0
  4. package/dist/chunk-5NF3BSD6.js.map +7 -0
  5. package/dist/chunk-IIU6U7TE.js +307 -0
  6. package/dist/chunk-IIU6U7TE.js.map +7 -0
  7. package/dist/chunk-LQZTKH3U.js +307 -0
  8. package/dist/chunk-LQZTKH3U.js.map +7 -0
  9. package/dist/cli.d.ts +11 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +84 -0
  12. package/dist/cli.js.map +7 -0
  13. package/dist/commands/init.d.ts +7 -0
  14. package/dist/commands/init.d.ts.map +1 -0
  15. package/dist/commands/init.js +333 -0
  16. package/dist/commands/init.js.map +1 -0
  17. package/dist/commands/post.d.ts +20 -0
  18. package/dist/commands/post.d.ts.map +1 -0
  19. package/dist/commands/post.js +183 -0
  20. package/dist/commands/post.js.map +1 -0
  21. package/dist/commands/pre.d.ts +18 -0
  22. package/dist/commands/pre.d.ts.map +1 -0
  23. package/dist/commands/pre.js +102 -0
  24. package/dist/commands/pre.js.map +1 -0
  25. package/dist/commands/status.d.ts +5 -0
  26. package/dist/commands/status.d.ts.map +1 -0
  27. package/dist/commands/status.js +48 -0
  28. package/dist/commands/status.js.map +1 -0
  29. package/dist/daemon-V2QDZTUB.js +89 -0
  30. package/dist/daemon-V2QDZTUB.js.map +7 -0
  31. package/dist/daemon.d.ts +9 -0
  32. package/dist/daemon.d.ts.map +1 -0
  33. package/dist/daemon.js +112 -0
  34. package/dist/daemon.js.map +1 -0
  35. package/dist/index.d.ts +15 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +36 -0
  38. package/dist/index.js.map +7 -0
  39. package/dist/parser.d.ts +21 -0
  40. package/dist/parser.d.ts.map +1 -0
  41. package/dist/parser.js +152 -0
  42. package/dist/parser.js.map +1 -0
  43. package/dist/reviewer/index.js +544 -0
  44. package/dist/reviewer/index.js.map +7 -0
  45. package/dist/rules.d.ts +21 -0
  46. package/dist/rules.d.ts.map +1 -0
  47. package/dist/rules.js +165 -0
  48. package/dist/rules.js.map +1 -0
  49. package/dist/status-Q6Z4TFJZ.js +52 -0
  50. package/dist/status-Q6Z4TFJZ.js.map +7 -0
  51. package/dist/types.d.ts +69 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +13 -0
  54. package/dist/types.js.map +1 -0
  55. package/package.json +52 -0
package/dist/rules.js ADDED
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Rule matching engine for guard
3
+ */
4
+ import { isPathWithinAllowed, normalizePath } from './parser.js';
5
+ // Cache compiled RegExp patterns to avoid recompilation on every check
6
+ const regexCache = new Map();
7
+ function getRegex(pattern) {
8
+ let regex = regexCache.get(pattern);
9
+ if (!regex) {
10
+ regex = new RegExp(pattern);
11
+ regexCache.set(pattern, regex);
12
+ }
13
+ return regex;
14
+ }
15
+ /**
16
+ * Check if command matches a block rule
17
+ */
18
+ export function matchesBlockRule(cmdInfo, rule) {
19
+ // Check command name
20
+ if (rule.cmd) {
21
+ const cmds = Array.isArray(rule.cmd) ? rule.cmd : [rule.cmd];
22
+ if (!cmds.includes(cmdInfo.cmd)) {
23
+ return false;
24
+ }
25
+ }
26
+ // Check subcommand (for git, etc.)
27
+ if (rule.subcommand && cmdInfo.subcommand !== rule.subcommand) {
28
+ return false;
29
+ }
30
+ // Check flags
31
+ if (rule.flags) {
32
+ const ruleFlags = Array.isArray(rule.flags) ? rule.flags : [rule.flags];
33
+ const mode = rule.flagMode || 'all';
34
+ if (mode === 'any') {
35
+ const hasAnyFlag = ruleFlags.some(f => cmdInfo.flags.includes(f));
36
+ if (!hasAnyFlag) {
37
+ return false;
38
+ }
39
+ }
40
+ else {
41
+ const hasAllFlags = ruleFlags.every(f => cmdInfo.flags.includes(f));
42
+ if (!hasAllFlags) {
43
+ return false;
44
+ }
45
+ }
46
+ }
47
+ // Check path patterns (using normalized paths to catch traversal)
48
+ if (rule.pathPatterns) {
49
+ const patterns = Array.isArray(rule.pathPatterns)
50
+ ? rule.pathPatterns
51
+ : [rule.pathPatterns];
52
+ const pathsToCheck = cmdInfo.paths.length > 0 ? cmdInfo.paths : cmdInfo.args;
53
+ if (pathsToCheck.length === 0) {
54
+ return false;
55
+ }
56
+ const matchesPath = pathsToCheck.some(p => {
57
+ const pathInfo = normalizePath(p);
58
+ // Check both original AND normalized path for block rules
59
+ return patterns.some(pattern => {
60
+ const regex = getRegex(pattern);
61
+ return regex.test(pathInfo.original) || regex.test(pathInfo.normalized);
62
+ });
63
+ });
64
+ if (!matchesPath) {
65
+ return false;
66
+ }
67
+ }
68
+ // Check arg patterns
69
+ if (rule.argPatterns) {
70
+ const patterns = Array.isArray(rule.argPatterns)
71
+ ? rule.argPatterns
72
+ : [rule.argPatterns];
73
+ const rawStr = cmdInfo.raw.join(' ');
74
+ const matchesArg = patterns.some(pattern => getRegex(pattern).test(rawStr));
75
+ if (!matchesArg) {
76
+ return false;
77
+ }
78
+ }
79
+ return true;
80
+ }
81
+ /**
82
+ * Check if command matches an allow rule
83
+ */
84
+ export function matchesAllowRule(cmdInfo, rule) {
85
+ if (rule.cmd) {
86
+ const cmds = Array.isArray(rule.cmd) ? rule.cmd : [rule.cmd];
87
+ if (!cmds.includes(cmdInfo.cmd)) {
88
+ return false;
89
+ }
90
+ }
91
+ if (rule.pathPatterns) {
92
+ const patterns = Array.isArray(rule.pathPatterns)
93
+ ? rule.pathPatterns
94
+ : [rule.pathPatterns];
95
+ const pathsToCheck = cmdInfo.paths.length > 0 ? cmdInfo.paths : cmdInfo.args;
96
+ if (pathsToCheck.length === 0) {
97
+ return false;
98
+ }
99
+ const matchesPath = pathsToCheck.some(p => {
100
+ const pathInfo = normalizePath(p);
101
+ return patterns.some(pattern => isPathWithinAllowed(pathInfo, pattern));
102
+ });
103
+ if (!matchesPath) {
104
+ return false;
105
+ }
106
+ }
107
+ return true;
108
+ }
109
+ /**
110
+ * Check pipeline for dangerous pipe patterns (curl | bash)
111
+ */
112
+ export function checkPipeline(ast, rules) {
113
+ if (!ast || ast.type !== 'Script') {
114
+ return null;
115
+ }
116
+ for (const cmd of ast.commands || []) {
117
+ if (cmd.type !== 'Pipeline') {
118
+ continue;
119
+ }
120
+ const pipeCommands = (cmd.commands || [])
121
+ .map(c => c.name?.text)
122
+ .filter((t) => Boolean(t));
123
+ for (const rule of rules.block || []) {
124
+ if (!rule.pipeTo) {
125
+ continue;
126
+ }
127
+ const cmds = Array.isArray(rule.cmd) ? rule.cmd : [rule.cmd];
128
+ const pipes = Array.isArray(rule.pipeTo) ? rule.pipeTo : [rule.pipeTo];
129
+ // Find if source command exists in pipeline
130
+ for (let i = 0; i < pipeCommands.length; i++) {
131
+ if (cmds.includes(pipeCommands[i])) {
132
+ // Check if ANY subsequent command is a dangerous target
133
+ for (let j = i + 1; j < pipeCommands.length; j++) {
134
+ if (pipes.includes(pipeCommands[j])) {
135
+ return rule;
136
+ }
137
+ }
138
+ }
139
+ }
140
+ }
141
+ }
142
+ return null;
143
+ }
144
+ /**
145
+ * Check a command against all rules
146
+ */
147
+ export function checkCommand(cmdInfo, rules) {
148
+ // First check allow rules
149
+ for (const rule of rules.allow || []) {
150
+ if (matchesAllowRule(cmdInfo, rule)) {
151
+ return { blocked: false, reason: `Allowed: ${rule.name}` };
152
+ }
153
+ }
154
+ // Then check block rules
155
+ for (const rule of rules.block || []) {
156
+ if (rule.pipeTo) {
157
+ continue;
158
+ } // Handled separately
159
+ if (matchesBlockRule(cmdInfo, rule)) {
160
+ return { blocked: true, rule };
161
+ }
162
+ }
163
+ return { blocked: false };
164
+ }
165
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import {
2
+ checkProviderStatus,
3
+ getAvailableProviders
4
+ } from "./chunk-3CILH2TO.js";
5
+
6
+ // src/commands/status.ts
7
+ async function runStatus() {
8
+ console.log("Checking LLM providers...\n");
9
+ const available = getAvailableProviders();
10
+ if (available.length === 0) {
11
+ console.log("No providers configured.");
12
+ console.log("Set CEREBRAS_API_KEY, GROQ_API_KEY, or OPENAI_API_KEY");
13
+ return;
14
+ }
15
+ console.log(`Configured: ${available.join(", ")}
16
+ `);
17
+ const statuses = await checkProviderStatus();
18
+ for (const status of statuses) {
19
+ const icon = status.available ? "\u2713" : "\u2717";
20
+ console.log(`${icon} ${status.provider.toUpperCase()}`);
21
+ if (status.error) {
22
+ console.log(` Error: ${status.error}`);
23
+ continue;
24
+ }
25
+ if (status.limits) {
26
+ const l = status.limits;
27
+ if (l.requestsPerMinute && l.requestsRemainingMinute) {
28
+ const pct = Math.round(l.requestsRemainingMinute / l.requestsPerMinute * 100);
29
+ console.log(` Requests/min: ${l.requestsRemainingMinute.toLocaleString()}/${l.requestsPerMinute.toLocaleString()} (${pct}%)`);
30
+ }
31
+ if (l.requestsRemainingDay) {
32
+ const limit = l.requestsPerDay || 14400;
33
+ const used = limit - l.requestsRemainingDay;
34
+ console.log(` Requests/day: ${l.requestsRemainingDay.toLocaleString()} remaining (${used.toLocaleString()} used)`);
35
+ }
36
+ if (l.tokensPerMinute && l.tokensRemainingMinute) {
37
+ const pct = Math.round(l.tokensRemainingMinute / l.tokensPerMinute * 100);
38
+ console.log(` Tokens/min: ${l.tokensRemainingMinute.toLocaleString()}/${l.tokensPerMinute.toLocaleString()} (${pct}%)`);
39
+ }
40
+ if (l.tokensRemainingDay) {
41
+ const limit = l.tokensPerDay || 1e6;
42
+ const used = limit - l.tokensRemainingDay;
43
+ console.log(` Tokens/day: ${l.tokensRemainingDay.toLocaleString()} remaining (${used.toLocaleString()} used)`);
44
+ }
45
+ }
46
+ console.log("");
47
+ }
48
+ }
49
+ export {
50
+ runStatus
51
+ };
52
+ //# sourceMappingURL=status-Q6Z4TFJZ.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/commands/status.ts"],
4
+ "sourcesContent": ["/**\n * sherpa status - Show LLM provider status and rate limits\n */\n\nimport { checkProviderStatus, getAvailableProviders } from '@goobits/sherpa-core'\n\nexport async function runStatus(): Promise<void> {\n\tconsole.log('Checking LLM providers...\\n')\n\n\tconst available = getAvailableProviders()\n\n\tif (available.length === 0) {\n\t\tconsole.log('No providers configured.')\n\t\tconsole.log('Set CEREBRAS_API_KEY, GROQ_API_KEY, or OPENAI_API_KEY')\n\t\treturn\n\t}\n\n\tconsole.log(`Configured: ${ available.join(', ') }\\n`)\n\n\tconst statuses = await checkProviderStatus()\n\n\tfor (const status of statuses) {\n\t\tconst icon = status.available ? '\u2713' : '\u2717'\n\t\tconsole.log(`${ icon } ${ status.provider.toUpperCase() }`)\n\n\t\tif (status.error) {\n\t\t\tconsole.log(` Error: ${ status.error }`)\n\t\t\tcontinue\n\t\t}\n\n\t\tif (status.limits) {\n\t\t\tconst l = status.limits\n\n\t\t\t// Show requests\n\t\t\tif (l.requestsPerMinute && l.requestsRemainingMinute) {\n\t\t\t\tconst pct = Math.round((l.requestsRemainingMinute / l.requestsPerMinute) * 100)\n\t\t\t\tconsole.log(` Requests/min: ${ l.requestsRemainingMinute.toLocaleString() }/${ l.requestsPerMinute.toLocaleString() } (${ pct }%)`)\n\t\t\t}\n\t\t\tif (l.requestsRemainingDay) {\n\t\t\t\tconst limit = l.requestsPerDay || 14400 // Cerebras free tier default\n\t\t\t\tconst used = limit - l.requestsRemainingDay\n\t\t\t\tconsole.log(` Requests/day: ${ l.requestsRemainingDay.toLocaleString() } remaining (${ used.toLocaleString() } used)`)\n\t\t\t}\n\n\t\t\t// Show tokens\n\t\t\tif (l.tokensPerMinute && l.tokensRemainingMinute) {\n\t\t\t\tconst pct = Math.round((l.tokensRemainingMinute / l.tokensPerMinute) * 100)\n\t\t\t\tconsole.log(` Tokens/min: ${ l.tokensRemainingMinute.toLocaleString() }/${ l.tokensPerMinute.toLocaleString() } (${ pct }%)`)\n\t\t\t}\n\t\t\tif (l.tokensRemainingDay) {\n\t\t\t\tconst limit = l.tokensPerDay || 1000000 // Cerebras free tier default\n\t\t\t\tconst used = limit - l.tokensRemainingDay\n\t\t\t\tconsole.log(` Tokens/day: ${ l.tokensRemainingDay.toLocaleString() } remaining (${ used.toLocaleString() } used)`)\n\t\t\t}\n\t\t}\n\t\tconsole.log('')\n\t}\n}\n"],
5
+ "mappings": ";;;;;;AAMA,eAAsB,YAA2B;AAChD,UAAQ,IAAI,6BAA6B;AAEzC,QAAM,YAAY,sBAAsB;AAExC,MAAI,UAAU,WAAW,GAAG;AAC3B,YAAQ,IAAI,0BAA0B;AACtC,YAAQ,IAAI,uDAAuD;AACnE;AAAA,EACD;AAEA,UAAQ,IAAI,eAAgB,UAAU,KAAK,IAAI,CAAE;AAAA,CAAI;AAErD,QAAM,WAAW,MAAM,oBAAoB;AAE3C,aAAW,UAAU,UAAU;AAC9B,UAAM,OAAO,OAAO,YAAY,WAAM;AACtC,YAAQ,IAAI,GAAI,IAAK,IAAK,OAAO,SAAS,YAAY,CAAE,EAAE;AAE1D,QAAI,OAAO,OAAO;AACjB,cAAQ,IAAI,YAAa,OAAO,KAAM,EAAE;AACxC;AAAA,IACD;AAEA,QAAI,OAAO,QAAQ;AAClB,YAAM,IAAI,OAAO;AAGjB,UAAI,EAAE,qBAAqB,EAAE,yBAAyB;AACrD,cAAM,MAAM,KAAK,MAAO,EAAE,0BAA0B,EAAE,oBAAqB,GAAG;AAC9E,gBAAQ,IAAI,mBAAoB,EAAE,wBAAwB,eAAe,CAAE,IAAK,EAAE,kBAAkB,eAAe,CAAE,KAAM,GAAI,IAAI;AAAA,MACpI;AACA,UAAI,EAAE,sBAAsB;AAC3B,cAAM,QAAQ,EAAE,kBAAkB;AAClC,cAAM,OAAO,QAAQ,EAAE;AACvB,gBAAQ,IAAI,mBAAoB,EAAE,qBAAqB,eAAe,CAAE,eAAgB,KAAK,eAAe,CAAE,QAAQ;AAAA,MACvH;AAGA,UAAI,EAAE,mBAAmB,EAAE,uBAAuB;AACjD,cAAM,MAAM,KAAK,MAAO,EAAE,wBAAwB,EAAE,kBAAmB,GAAG;AAC1E,gBAAQ,IAAI,iBAAkB,EAAE,sBAAsB,eAAe,CAAE,IAAK,EAAE,gBAAgB,eAAe,CAAE,KAAM,GAAI,IAAI;AAAA,MAC9H;AACA,UAAI,EAAE,oBAAoB;AACzB,cAAM,QAAQ,EAAE,gBAAgB;AAChC,cAAM,OAAO,QAAQ,EAAE;AACvB,gBAAQ,IAAI,iBAAkB,EAAE,mBAAmB,eAAe,CAAE,eAAgB,KAAK,eAAe,CAAE,QAAQ;AAAA,MACnH;AAAA,IACD;AACA,YAAQ,IAAI,EAAE;AAAA,EACf;AACD;",
6
+ "names": []
7
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Type definitions for guard
3
+ */
4
+ /** Parsed command info extracted from AST */
5
+ export interface CommandInfo {
6
+ cmd: string;
7
+ args: string[];
8
+ flags: string[];
9
+ paths: string[];
10
+ raw: string[];
11
+ subcommand?: string;
12
+ subArgs?: string[];
13
+ }
14
+ /** Normalized path info for traversal detection */
15
+ export interface PathInfo {
16
+ original: string;
17
+ normalized: string;
18
+ hasTraversal: boolean;
19
+ isAbsolute: boolean;
20
+ }
21
+ /** Rule definition for blocking/allowing commands */
22
+ export interface Rule {
23
+ name: string;
24
+ cmd?: string | string[];
25
+ subcommand?: string;
26
+ flags?: string | string[];
27
+ flagMode?: 'all' | 'any';
28
+ pathPatterns?: string | string[];
29
+ argPatterns?: string | string[];
30
+ pipeTo?: string | string[];
31
+ reason: string;
32
+ }
33
+ /** Rules configuration */
34
+ export interface RulesConfig {
35
+ block: Rule[];
36
+ allow: Rule[];
37
+ }
38
+ /** Check result */
39
+ export interface CheckResult {
40
+ blocked: boolean;
41
+ rule?: Rule;
42
+ reason?: string;
43
+ }
44
+ /** Bash parser AST node types */
45
+ export interface ASTNode {
46
+ type: string;
47
+ commands?: ASTNode[];
48
+ left?: ASTNode;
49
+ right?: ASTNode;
50
+ list?: ASTNode[];
51
+ name?: {
52
+ text: string;
53
+ };
54
+ suffix?: Array<{
55
+ text: string;
56
+ }>;
57
+ }
58
+ /** Guard configuration */
59
+ export interface GuardConfig {
60
+ maxTokens: number;
61
+ previewTokens: number;
62
+ scratchDir: string;
63
+ maxAgeMinutes: number;
64
+ maxScratchSizeMB: number;
65
+ socketPath: string;
66
+ }
67
+ /** Default guard configuration */
68
+ export declare const DEFAULT_CONFIG: GuardConfig;
69
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,6CAA6C;AAC7C,MAAM,WAAW,WAAW;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,mDAAmD;AACnD,MAAM,WAAW,QAAQ;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;CACpB;AAED,qDAAqD;AACrD,MAAM,WAAW,IAAI;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CACf;AAED,0BAA0B;AAC1B,MAAM,WAAW,WAAW;IAC3B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE,IAAI,EAAE,CAAC;CACd;AAED,mBAAmB;AACnB,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,iCAAiC;AACjC,MAAM,WAAW,OAAO;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACxB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjC;AAED,0BAA0B;AAC1B,MAAM,WAAW,WAAW;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,kCAAkC;AAClC,eAAO,MAAM,cAAc,EAAE,WAO5B,CAAA"}
package/dist/types.js ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Type definitions for guard
3
+ */
4
+ /** Default guard configuration */
5
+ export const DEFAULT_CONFIG = {
6
+ maxTokens: 2000,
7
+ previewTokens: 500,
8
+ scratchDir: '.claude/scratch',
9
+ maxAgeMinutes: 60,
10
+ maxScratchSizeMB: 50,
11
+ socketPath: '/tmp/mcp-guard.sock'
12
+ };
13
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAoEH,kCAAkC;AAClC,MAAM,CAAC,MAAM,cAAc,GAAgB;IAC1C,SAAS,EAAE,IAAI;IACf,aAAa,EAAE,GAAG;IAClB,UAAU,EAAE,iBAAiB;IAC7B,aAAa,EAAE,EAAE;IACjB,gBAAgB,EAAE,EAAE;IACpB,UAAU,EAAE,qBAAqB;CACjC,CAAA"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@goobits/sherpa",
3
+ "version": "1.0.1",
4
+ "description": "CLI guard for safer AI coding - blocks dangerous bash commands and manages output context",
5
+ "type": "module",
6
+ "bin": {
7
+ "sherpa": "dist/cli.js"
8
+ },
9
+ "main": "dist/index.js",
10
+ "types": "dist/index.d.ts",
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc --emitDeclarationOnly && node scripts/build.mjs",
16
+ "dev": "tsc --watch",
17
+ "typecheck": "tsc --noEmit",
18
+ "test": "vitest run",
19
+ "test:watch": "vitest",
20
+ "prepublishOnly": "npm run build && npm run test"
21
+ },
22
+ "keywords": [
23
+ "claude",
24
+ "claude-code",
25
+ "mcp",
26
+ "ai",
27
+ "coding",
28
+ "safety",
29
+ "hooks",
30
+ "bash",
31
+ "guard"
32
+ ],
33
+ "license": "MIT",
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "https://github.com/goobits/sherpa.git",
37
+ "directory": "packages/sherpa"
38
+ },
39
+ "dependencies": {
40
+ "@modelcontextprotocol/sdk": "^1.0.0",
41
+ "bash-parser": "^0.5.0",
42
+ "glob": "^10.4.0",
43
+ "ignore": "^5.3.0",
44
+ "openai": "^4.77.0",
45
+ "tiktoken": "^1.0.0"
46
+ },
47
+ "devDependencies": {
48
+ "@goobits/sherpa-core": "workspace:*",
49
+ "esbuild": "^0.23.0",
50
+ "vitest": "^2.0.0"
51
+ }
52
+ }