@webpieces/webpieces-tooling 0.4.847 → 0.4.849

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/webpieces-tooling",
3
- "version": "0.4.847",
3
+ "version": "0.4.849",
4
4
  "description": "Complete webpieces tooling installation and the combined OpenClaw hook adapter.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -15,17 +15,17 @@
15
15
  "README.md"
16
16
  ],
17
17
  "dependencies": {
18
- "@webpieces/agent-workflow-rules": "0.4.847",
19
- "@webpieces/ai-hook-rules": "0.4.847",
20
- "@webpieces/code-rules": "0.4.847",
21
- "@webpieces/eslint-rules": "0.4.847",
22
- "@webpieces/hook-runtime": "0.4.847",
23
- "@webpieces/nx-webpieces-rules": "0.4.847",
24
- "@webpieces/pr-gate": "0.4.847",
25
- "@webpieces/repo-workflow-core": "0.4.847",
26
- "@webpieces/rules-config": "0.4.847",
27
- "@webpieces/tooling-common": "0.4.847",
28
- "@webpieces/rules-sdk": "0.4.847"
18
+ "@webpieces/agent-workflow-rules": "0.4.849",
19
+ "@webpieces/ai-hook-rules": "0.4.849",
20
+ "@webpieces/code-rules": "0.4.849",
21
+ "@webpieces/eslint-rules": "0.4.849",
22
+ "@webpieces/hook-runtime": "0.4.849",
23
+ "@webpieces/nx-webpieces-rules": "0.4.849",
24
+ "@webpieces/pr-gate": "0.4.849",
25
+ "@webpieces/repo-workflow-core": "0.4.849",
26
+ "@webpieces/rules-config": "0.4.849",
27
+ "@webpieces/tooling-common": "0.4.849",
28
+ "@webpieces/rules-sdk": "0.4.849"
29
29
  },
30
30
  "author": "Dean Hiller",
31
31
  "license": "Apache-2.0",
@@ -38,7 +38,7 @@
38
38
  "access": "public"
39
39
  },
40
40
  "devDependencies": {
41
- "@webpieces/tooling-testkit": "0.4.847"
41
+ "@webpieces/tooling-testkit": "0.4.849"
42
42
  },
43
43
  "types": "./src/index.d.ts"
44
44
  }
@@ -22,8 +22,8 @@ class OpenclawHandlerResult {
22
22
  }
23
23
  }
24
24
  const TOOL_MAP = {
25
- 'write': 'Write',
26
- 'edit': 'Edit',
25
+ write: 'Write',
26
+ edit: 'Edit',
27
27
  };
28
28
  // webpieces-disable no-function-outside-class -- existing OpenClaw callback and stateless adapter helpers moved intact; the SDK invokes this module function
29
29
  function mapToolName(openclawName) {
@@ -31,6 +31,7 @@ function mapToolName(openclawName) {
31
31
  }
32
32
  // webpieces-disable no-any-unknown -- openclaw SDK passes opaque tool arguments
33
33
  // webpieces-disable no-function-outside-class -- existing OpenClaw callback and stateless adapter helpers moved intact; the SDK invokes this module function
34
+ // webpieces-disable no-any-unknown -- external JSON or runtime exports are validated before policy execution
34
35
  function mapToolInput(toolName, args) {
35
36
  const filePath = typeof args['path'] === 'string' ? args['path'] : null;
36
37
  if (!filePath)
@@ -74,10 +75,11 @@ async function handler(event, _context) {
74
75
  const loaded = (0, rules_config_2.loadAndValidate)(wsRoot);
75
76
  const source = new ai_hook_rules_1.SourceHookRules().load(loaded);
76
77
  const guards = new agent_workflow_rules_1.WorkflowHookRules().load(loaded);
77
- const result = new hook_runtime_1.HookFileEvaluation().evaluate(toolKind, input, loaded, new hook_runtime_1.HookRuleSet([...source.builtInRules, ...guards.rules, ...source.extensionRules], [...source.configuredRules, ...guards.configuredRules]));
78
+ const result = new hook_runtime_1.HookFileEvaluation().evaluate(toolKind, input, loaded, new hook_runtime_1.HookRuleSet([...source.contributedRules, ...guards.rules, ...source.matchRules]));
78
79
  if (!result)
79
80
  return new OpenclawHandlerResult('approved');
80
81
  return new OpenclawHandlerResult('rejected', result.report);
82
+ // webpieces-disable no-any-unknown -- external JSON or runtime exports are validated before policy execution
81
83
  }
82
84
  catch (err) {
83
85
  const error = (0, to_error_1.toError)(err);
@@ -1 +1 @@
1
- {"version":3,"file":"openclaw-plugin.js","sourceRoot":"","sources":["../../../../../../packages/tooling/webpieces-tooling/src/adapters/openclaw-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path';\nimport * as fs from 'fs';\n\nimport { CONFIG_FILENAME, renderRuleFailForAi } from '@webpieces/rules-config';\nimport { SourceHookRules } from '@webpieces/ai-hook-rules';\nimport { WorkflowHookRules } from '@webpieces/agent-workflow-rules';\nimport { HookRuleSet, HookFileEvaluation } from '@webpieces/hook-runtime';\nimport { loadAndValidate } from '@webpieces/rules-config';\nimport { NormalizedToolInput, NormalizedEdit, ToolKind } from '@webpieces/hook-runtime';\nimport { InformAiError } from '@webpieces/tooling-common';\nimport { RuleFailError } from '@webpieces/rules-config';\nimport { toError } from '@webpieces/tooling-common/to-error';\n\ninterface ToolCallEvent {\n toolName: string;\n // webpieces-disable no-any-unknown -- openclaw SDK passes opaque tool arguments\n arguments: Record<string, unknown>;\n}\n\ninterface HookContext {\n // webpieces-disable no-any-unknown -- openclaw SDK context shape is opaque\n [key: string]: unknown;\n}\n\nclass OpenclawHandlerResult {\n readonly status: 'approved' | 'rejected';\n readonly reason: string | undefined;\n\n constructor(status: 'approved' | 'rejected', reason?: string) {\n this.status = status;\n this.reason = reason;\n }\n}\n\nconst TOOL_MAP: Record<string, ToolKind> = {\n 'write': 'Write',\n 'edit': 'Edit',\n};\n\n// webpieces-disable no-function-outside-class -- existing OpenClaw callback and stateless adapter helpers moved intact; the SDK invokes this module function\nfunction mapToolName(openclawName: string): ToolKind | null {\n return TOOL_MAP[openclawName] || null;\n}\n\n// webpieces-disable no-any-unknown -- openclaw SDK passes opaque tool arguments\n// webpieces-disable no-function-outside-class -- existing OpenClaw callback and stateless adapter helpers moved intact; the SDK invokes this module function\nfunction mapToolInput(toolName: string, args: Record<string, unknown>): NormalizedToolInput | null {\n const filePath = typeof args['path'] === 'string' ? args['path'] as string : null;\n if (!filePath) return null;\n\n if (toolName === 'write') {\n const content = typeof args['content'] === 'string' ? args['content'] as string : '';\n return new NormalizedToolInput(filePath, [new NormalizedEdit('', content)]);\n }\n if (toolName === 'edit') {\n const oldStr = typeof args['old_string'] === 'string' ? args['old_string'] as string : '';\n const newStr = typeof args['new_string'] === 'string' ? args['new_string'] as string : '';\n return new NormalizedToolInput(filePath, [new NormalizedEdit(oldStr, newStr)]);\n }\n return null;\n}\n\n// webpieces-disable no-function-outside-class -- existing OpenClaw callback and stateless adapter helpers moved intact; the SDK invokes this module function\nfunction findWorkspaceRoot(filePath: string): string | null {\n let dir = path.dirname(filePath);\n while (true) {\n if (fs.existsSync(path.join(dir, CONFIG_FILENAME))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n// webpieces-disable no-function-outside-class -- existing OpenClaw callback and stateless adapter helpers moved intact; the SDK invokes this module function\nexport default async function handler(\n event: ToolCallEvent,\n _context: HookContext,\n): Promise<OpenclawHandlerResult | undefined> {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const toolKind = mapToolName(event.toolName);\n if (!toolKind) return undefined;\n\n const input = mapToolInput(event.toolName, event.arguments);\n if (!input) return undefined;\n\n const wsRoot = findWorkspaceRoot(input.filePath);\n if (!wsRoot) return undefined;\n\n const loaded = loadAndValidate(wsRoot);\n const source = new SourceHookRules().load(loaded);\n const guards = new WorkflowHookRules().load(loaded);\n const result = new HookFileEvaluation().evaluate(toolKind, input, loaded,\n new HookRuleSet([...source.builtInRules, ...guards.rules, ...source.extensionRules], [...source.configuredRules, ...guards.configuredRules]));\n if (!result) return new OpenclawHandlerResult('approved');\n return new OpenclawHandlerResult('rejected', result.report);\n } catch (err: unknown) {\n const error = toError(err);\n // An escaped RuleFailError or InformAiError carries an AI-readable message; anything else is\n // an unexpected bug. All reject (fail closed).\n let msg: string;\n if (error instanceof RuleFailError) {\n msg = renderRuleFailForAi(error);\n } else if (error instanceof InformAiError) {\n msg = error.message;\n } else {\n msg = `[ai-hooks] openclaw adapter crashed — failing closed: ${error.message}`;\n }\n return new OpenclawHandlerResult('rejected', msg);\n }\n}\n"]}
1
+ {"version":3,"file":"openclaw-plugin.js","sourceRoot":"","sources":["../../../../../../packages/tooling/webpieces-tooling/src/adapters/openclaw-plugin.ts"],"names":[],"mappings":";;AA2EA,0BAyCC;;AApHD,mDAA6B;AAC7B,+CAAyB;AAEzB,0DAA+E;AAC/E,4DAA2D;AAC3D,0EAAoE;AACpE,0DAA0E;AAC1E,0DAA0D;AAC1D,0DAAwF;AACxF,8DAA0D;AAC1D,0DAAwD;AACxD,iEAA6D;AAa7D,MAAM,qBAAqB;IACd,MAAM,CAA0B;IAChC,MAAM,CAAqB;IAEpC,YAAY,MAA+B,EAAE,MAAe;QACxD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;CACJ;AAED,MAAM,QAAQ,GAA6B;IACvC,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;CACf,CAAC;AAEF,6JAA6J;AAC7J,SAAS,WAAW,CAAC,YAAoB;IACrC,OAAO,QAAQ,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC;AAC1C,CAAC;AAED,gFAAgF;AAChF,6JAA6J;AAC7J,6GAA6G;AAC7G,SAAS,YAAY,CAAC,QAAgB,EAAE,IAA6B;IACjE,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAI,CAAC,MAAM,CAAY,CAAC,CAAC,CAAC,IAAI,CAAC;IACpF,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE3B,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAI,CAAC,SAAS,CAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QACvF,OAAO,IAAI,kCAAmB,CAAC,QAAQ,EAAE,CAAC,IAAI,6BAAc,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAI,CAAC,YAAY,CAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5F,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAI,CAAC,YAAY,CAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5F,OAAO,IAAI,kCAAmB,CAAC,QAAQ,EAAE,CAAC,IAAI,6BAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,6JAA6J;AAC7J,SAAS,iBAAiB,CAAC,QAAgB;IACvC,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,OAAO,IAAI,EAAE,CAAC;QACV,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,8BAAe,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAChC,GAAG,GAAG,MAAM,CAAC;IACjB,CAAC;AACL,CAAC;AAED,6JAA6J;AAC9I,KAAK,UAAU,OAAO,CACjC,KAAoB,EACpB,QAAqB;IAErB,8DAA8D;IAC9D,IAAI,CAAC;QACD,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC7C,IAAI,CAAC,QAAQ;YAAE,OAAO,SAAS,CAAC;QAEhC,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAC5D,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAE7B,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACjD,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAE9B,MAAM,MAAM,GAAG,IAAA,8BAAe,EAAC,MAAM,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,IAAI,+BAAe,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,wCAAiB,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,iCAAkB,EAAE,CAAC,QAAQ,CAC5C,QAAQ,EACR,KAAK,EACL,MAAM,EACN,IAAI,0BAAW,CAAC,CAAC,GAAG,MAAM,CAAC,gBAAgB,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CACvF,CAAC;QACF,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,qBAAqB,CAAC,UAAU,CAAC,CAAC;QAC1D,OAAO,IAAI,qBAAqB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAChE,6GAA6G;IAC7G,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,IAAA,kBAAO,EAAC,GAAG,CAAC,CAAC;QAC3B,6FAA6F;QAC7F,+CAA+C;QAC/C,IAAI,GAAW,CAAC;QAChB,IAAI,KAAK,YAAY,4BAAa,EAAE,CAAC;YACjC,GAAG,GAAG,IAAA,kCAAmB,EAAC,KAAK,CAAC,CAAC;QACrC,CAAC;aAAM,IAAI,KAAK,YAAY,8BAAa,EAAE,CAAC;YACxC,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC;QACxB,CAAC;aAAM,CAAC;YACJ,GAAG,GAAG,yDAAyD,KAAK,CAAC,OAAO,EAAE,CAAC;QACnF,CAAC;QACD,OAAO,IAAI,qBAAqB,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACtD,CAAC;AACL,CAAC","sourcesContent":["import * as path from 'path';\nimport * as fs from 'fs';\n\nimport { CONFIG_FILENAME, renderRuleFailForAi } from '@webpieces/rules-config';\nimport { SourceHookRules } from '@webpieces/ai-hook-rules';\nimport { WorkflowHookRules } from '@webpieces/agent-workflow-rules';\nimport { HookRuleSet, HookFileEvaluation } from '@webpieces/hook-runtime';\nimport { loadAndValidate } from '@webpieces/rules-config';\nimport { NormalizedToolInput, NormalizedEdit, ToolKind } from '@webpieces/hook-runtime';\nimport { InformAiError } from '@webpieces/tooling-common';\nimport { RuleFailError } from '@webpieces/rules-config';\nimport { toError } from '@webpieces/tooling-common/to-error';\n\ninterface ToolCallEvent {\n toolName: string;\n // webpieces-disable no-any-unknown -- openclaw SDK passes opaque tool arguments\n arguments: Record<string, unknown>;\n}\n\ninterface HookContext {\n // webpieces-disable no-any-unknown -- openclaw SDK context shape is opaque\n [key: string]: unknown;\n}\n\nclass OpenclawHandlerResult {\n readonly status: 'approved' | 'rejected';\n readonly reason: string | undefined;\n\n constructor(status: 'approved' | 'rejected', reason?: string) {\n this.status = status;\n this.reason = reason;\n }\n}\n\nconst TOOL_MAP: Record<string, ToolKind> = {\n write: 'Write',\n edit: 'Edit',\n};\n\n// webpieces-disable no-function-outside-class -- existing OpenClaw callback and stateless adapter helpers moved intact; the SDK invokes this module function\nfunction mapToolName(openclawName: string): ToolKind | null {\n return TOOL_MAP[openclawName] || null;\n}\n\n// webpieces-disable no-any-unknown -- openclaw SDK passes opaque tool arguments\n// webpieces-disable no-function-outside-class -- existing OpenClaw callback and stateless adapter helpers moved intact; the SDK invokes this module function\n// webpieces-disable no-any-unknown -- external JSON or runtime exports are validated before policy execution\nfunction mapToolInput(toolName: string, args: Record<string, unknown>): NormalizedToolInput | null {\n const filePath = typeof args['path'] === 'string' ? (args['path'] as string) : null;\n if (!filePath) return null;\n\n if (toolName === 'write') {\n const content = typeof args['content'] === 'string' ? (args['content'] as string) : '';\n return new NormalizedToolInput(filePath, [new NormalizedEdit('', content)]);\n }\n if (toolName === 'edit') {\n const oldStr = typeof args['old_string'] === 'string' ? (args['old_string'] as string) : '';\n const newStr = typeof args['new_string'] === 'string' ? (args['new_string'] as string) : '';\n return new NormalizedToolInput(filePath, [new NormalizedEdit(oldStr, newStr)]);\n }\n return null;\n}\n\n// webpieces-disable no-function-outside-class -- existing OpenClaw callback and stateless adapter helpers moved intact; the SDK invokes this module function\nfunction findWorkspaceRoot(filePath: string): string | null {\n let dir = path.dirname(filePath);\n while (true) {\n if (fs.existsSync(path.join(dir, CONFIG_FILENAME))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n// webpieces-disable no-function-outside-class -- existing OpenClaw callback and stateless adapter helpers moved intact; the SDK invokes this module function\nexport default async function handler(\n event: ToolCallEvent,\n _context: HookContext,\n): Promise<OpenclawHandlerResult | undefined> {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const toolKind = mapToolName(event.toolName);\n if (!toolKind) return undefined;\n\n const input = mapToolInput(event.toolName, event.arguments);\n if (!input) return undefined;\n\n const wsRoot = findWorkspaceRoot(input.filePath);\n if (!wsRoot) return undefined;\n\n const loaded = loadAndValidate(wsRoot);\n const source = new SourceHookRules().load(loaded);\n const guards = new WorkflowHookRules().load(loaded);\n const result = new HookFileEvaluation().evaluate(\n toolKind,\n input,\n loaded,\n new HookRuleSet([...source.contributedRules, ...guards.rules, ...source.matchRules]),\n );\n if (!result) return new OpenclawHandlerResult('approved');\n return new OpenclawHandlerResult('rejected', result.report);\n // webpieces-disable no-any-unknown -- external JSON or runtime exports are validated before policy execution\n } catch (err: unknown) {\n const error = toError(err);\n // An escaped RuleFailError or InformAiError carries an AI-readable message; anything else is\n // an unexpected bug. All reject (fail closed).\n let msg: string;\n if (error instanceof RuleFailError) {\n msg = renderRuleFailForAi(error);\n } else if (error instanceof InformAiError) {\n msg = error.message;\n } else {\n msg = `[ai-hooks] openclaw adapter crashed — failing closed: ${error.message}`;\n }\n return new OpenclawHandlerResult('rejected', msg);\n }\n}\n"]}