oh-my-harness 0.4.1 → 0.4.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.
@@ -1,5 +1,5 @@
1
1
  import path from "path";
2
- import { renderTemplate, validateParams } from "./template-engine.js";
2
+ import { renderTemplate, validateParams, applyDefaults } from "./template-engine.js";
3
3
  export async function convertHookEntries(entries, registry, projectDir) {
4
4
  const hooksConfig = {};
5
5
  const scripts = new Map();
@@ -11,7 +11,8 @@ export async function convertHookEntries(entries, registry, projectDir) {
11
11
  errors.push(`Unknown block id: "${entry.block}"`);
12
12
  continue;
13
13
  }
14
- const paramErrors = validateParams(block, entry.params);
14
+ const resolvedParams = applyDefaults(block, entry.params);
15
+ const paramErrors = validateParams(block, resolvedParams);
15
16
  if (paramErrors.length > 0) {
16
17
  errors.push(...paramErrors);
17
18
  continue;
@@ -23,7 +24,7 @@ export async function convertHookEntries(entries, registry, projectDir) {
23
24
  seenBlockIds.add(entry.block);
24
25
  let scriptContent;
25
26
  try {
26
- scriptContent = renderTemplate(block.template, entry.params);
27
+ scriptContent = renderTemplate(block.template, resolvedParams);
27
28
  }
28
29
  catch (err) {
29
30
  errors.push(`Failed to render block "${entry.block}": ${err.message}`);
@@ -1,3 +1,4 @@
1
1
  import type { BuildingBlock } from "./types.js";
2
2
  export declare function renderTemplate(template: string, params: Record<string, unknown>): string;
3
+ export declare function applyDefaults(block: BuildingBlock, params: Record<string, unknown>): Record<string, unknown>;
3
4
  export declare function validateParams(block: BuildingBlock, params: Record<string, unknown>): string[];
@@ -3,6 +3,15 @@ export function renderTemplate(template, params) {
3
3
  const compiled = Handlebars.compile(template);
4
4
  return compiled(params);
5
5
  }
6
+ export function applyDefaults(block, params) {
7
+ const result = { ...params };
8
+ for (const param of block.params) {
9
+ if (result[param.name] === undefined && param.default !== undefined) {
10
+ result[param.name] = param.default;
11
+ }
12
+ }
13
+ return result;
14
+ }
6
15
  export function validateParams(block, params) {
7
16
  const errors = [];
8
17
  for (const param of block.params) {
@@ -109,11 +109,11 @@ export declare const BuildingBlockSchema: z.ZodObject<{
109
109
  }>;
110
110
  export declare const HookEntrySchema: z.ZodObject<{
111
111
  block: z.ZodString;
112
- params: z.ZodRecord<z.ZodString, z.ZodUnknown>;
112
+ params: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
113
113
  }, "strip", z.ZodTypeAny, {
114
114
  params: Record<string, unknown>;
115
115
  block: string;
116
116
  }, {
117
- params: Record<string, unknown>;
118
117
  block: string;
118
+ params?: Record<string, unknown> | undefined;
119
119
  }>;
@@ -20,5 +20,5 @@ export const BuildingBlockSchema = z.object({
20
20
  });
21
21
  export const HookEntrySchema = z.object({
22
22
  block: z.string(),
23
- params: z.record(z.unknown()),
23
+ params: z.record(z.unknown()).default({}),
24
24
  });
@@ -65,7 +65,7 @@ export declare const HarnessConfigSchema: z.ZodObject<{
65
65
  content: string;
66
66
  priority?: number | undefined;
67
67
  }>, "many">;
68
- enforcement: z.ZodObject<{
68
+ enforcement: z.ZodDefault<z.ZodObject<{
69
69
  preCommit: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
70
70
  blockedPaths: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
71
71
  blockedCommands: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
@@ -95,16 +95,16 @@ export declare const HarnessConfigSchema: z.ZodObject<{
95
95
  command: string;
96
96
  pattern: string;
97
97
  }[] | undefined;
98
- }>;
98
+ }>>;
99
99
  hooks: z.ZodDefault<z.ZodArray<z.ZodObject<{
100
100
  block: z.ZodString;
101
- params: z.ZodRecord<z.ZodString, z.ZodUnknown>;
101
+ params: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
102
102
  }, "strip", z.ZodTypeAny, {
103
103
  params: Record<string, unknown>;
104
104
  block: string;
105
105
  }, {
106
- params: Record<string, unknown>;
107
106
  block: string;
107
+ params?: Record<string, unknown> | undefined;
108
108
  }>, "many">>;
109
109
  permissions: z.ZodDefault<z.ZodObject<{
110
110
  allow: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
@@ -172,23 +172,23 @@ export declare const HarnessConfigSchema: z.ZodObject<{
172
172
  content: string;
173
173
  priority?: number | undefined;
174
174
  }[];
175
- enforcement: {
176
- blockedPaths?: string[] | undefined;
177
- preCommit?: string[] | undefined;
178
- blockedCommands?: string[] | undefined;
179
- postSave?: {
180
- command: string;
181
- pattern: string;
182
- }[] | undefined;
183
- };
184
175
  permissions?: {
185
176
  allow?: string[] | undefined;
186
177
  deny?: string[] | undefined;
187
178
  } | undefined;
188
179
  version?: "1.0" | undefined;
189
180
  hooks?: {
190
- params: Record<string, unknown>;
191
181
  block: string;
182
+ params?: Record<string, unknown> | undefined;
192
183
  }[] | undefined;
184
+ enforcement?: {
185
+ blockedPaths?: string[] | undefined;
186
+ preCommit?: string[] | undefined;
187
+ blockedCommands?: string[] | undefined;
188
+ postSave?: {
189
+ command: string;
190
+ pattern: string;
191
+ }[] | undefined;
192
+ } | undefined;
193
193
  }>;
194
194
  export type HarnessConfig = z.infer<typeof HarnessConfigSchema>;
@@ -31,7 +31,7 @@ export const HarnessConfigSchema = z.object({
31
31
  pattern: z.string(),
32
32
  command: z.string(),
33
33
  })).default([]),
34
- }),
34
+ }).default({}),
35
35
  // Catalog-based hooks (v2)
36
36
  hooks: z.array(HookEntrySchema).default([]),
37
37
  // Permissions
@@ -101,14 +101,19 @@ hooks:
101
101
  typecheckCommand: "npx tsc --noEmit"
102
102
  - block: lint-on-save
103
103
  params:
104
- lintCommand: "npx eslint --fix"
105
- pattern: "*.{ts,tsx}"
104
+ filePattern: "*.ts"
105
+ command: "npx eslint --fix"
106
106
  - block: path-guard
107
107
  params:
108
- blockedPaths: ".next/,node_modules/,*.min.js"
108
+ blockedPaths:
109
+ - ".next/"
110
+ - "node_modules/"
111
+ - "*.min.js"
109
112
  - block: command-guard
110
113
  params:
111
- blockedCommands: "rm -rf /,sudo rm"
114
+ patterns:
115
+ - "rm -rf /"
116
+ - "sudo rm"
112
117
  permissions:
113
118
  allow:
114
119
  - "Bash(pnpm install*)"
@@ -145,14 +150,20 @@ hooks:
145
150
  testCommand: "uv run pytest"
146
151
  - block: lint-on-save
147
152
  params:
148
- lintCommand: "ruff check --fix"
149
- pattern: "*.py"
153
+ filePattern: "*.py"
154
+ command: "ruff check --fix"
150
155
  - block: path-guard
151
156
  params:
152
- blockedPaths: "__pycache__/,.venv/,*.pyc"
157
+ blockedPaths:
158
+ - "__pycache__/"
159
+ - ".venv/"
160
+ - "*.pyc"
153
161
  - block: command-guard
154
162
  params:
155
- blockedCommands: "rm -rf /,sudo rm,pip install"
163
+ patterns:
164
+ - "rm -rf /"
165
+ - "sudo rm"
166
+ - "pip install"
156
167
  permissions:
157
168
  allow:
158
169
  - "Bash(pytest*)"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-harness",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Tame your AI coding agents with natural language",
5
5
  "type": "module",
6
6
  "bin": {