@joshski/dust 0.1.109 → 0.1.110

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/dist/audits.js CHANGED
@@ -1865,6 +1865,168 @@ function slowTests() {
1865
1865
  - No changes to files outside \`.dust/\`
1866
1866
  `;
1867
1867
  }
1868
+ function overAbstraction() {
1869
+ return dedent`
1870
+ # Over-Abstraction
1871
+
1872
+ Identify violations of the "reasonably-dry" principle where code has been over-engineered with excessive abstraction.
1873
+
1874
+ ${ideasHint}
1875
+
1876
+ ## Scope
1877
+
1878
+ Detect these over-abstraction patterns:
1879
+
1880
+ 1. **Single-use abstractions** - Interfaces, base classes, or utility functions used in only one place
1881
+ 2. **Deep inheritance hierarchies** - Classes extending more than 2 levels deep
1882
+ 3. **Premature generalization** - Parameters always used with the same value, unused options/flags
1883
+ 4. **Excessive indirection** - Multiple layers of wrappers adding no value
1884
+
1885
+ ## Analysis Steps
1886
+
1887
+ ### 1. Find Single-Use Abstractions
1888
+
1889
+ Search for abstractions that are only used once:
1890
+
1891
+ 1. **Interfaces with one implementation**
1892
+ - Search for \`interface\` declarations
1893
+ - Check if each interface has only one implementing class
1894
+ - Flag interfaces that exist solely for testing (can be replaced with the concrete type)
1895
+
1896
+ 2. **Base classes with one subclass**
1897
+ - Search for \`abstract class\` or classes used as base classes
1898
+ - Count implementations extending each base class
1899
+ - Flag base classes with only one subclass
1900
+
1901
+ 3. **Utility functions called once**
1902
+ - Search for exported utility functions
1903
+ - Check call sites - if only called from one location, it's over-abstraction
1904
+ - Consider inlining single-use utilities
1905
+
1906
+ 4. **Generic types with one concrete usage**
1907
+ - Find generic type parameters: \`<T>\`, \`<TData>\`, etc.
1908
+ - Check if T is always the same type at all call sites
1909
+ - Flag generics that could be concrete types
1910
+
1911
+ ### 2. Detect Deep Inheritance Hierarchies
1912
+
1913
+ Find inheritance chains longer than 2 levels:
1914
+
1915
+ 1. Search for \`extends\` keywords in class declarations
1916
+ 2. Build inheritance tree for each class
1917
+ 3. Flag chains deeper than 2 (A extends B extends C extends D...)
1918
+ 4. Respect framework conventions (don't flag React.Component, etc.)
1919
+
1920
+ ### 3. Identify Premature Generalization
1921
+
1922
+ Look for flexibility that's never used:
1923
+
1924
+ 1. **Always-same parameter values**
1925
+ - Find function parameters
1926
+ - Check all call sites - if always the same value, it's not needed
1927
+ - Flag parameters that could be constants or removed
1928
+
1929
+ 2. **Unused configuration options**
1930
+ - Search for configuration objects/interfaces
1931
+ - Check which options are actually used
1932
+ - Flag options that are never set or always default
1933
+
1934
+ 3. **Unused function parameters**
1935
+ - Find parameters that aren't referenced in function bodies
1936
+ - Flag as candidates for removal
1937
+
1938
+ ### 4. Find Excessive Indirection
1939
+
1940
+ Detect wrapper chains that add no value:
1941
+
1942
+ 1. **Delegation chains**
1943
+ - Search for functions that only call another function
1944
+ - Flag wrappers that don't add logic, just forward calls
1945
+ - Example: \`function foo(x) { return bar(x) }\`
1946
+
1947
+ 2. **Proxy patterns without behavior**
1948
+ - Find classes that wrap another class
1949
+ - Check if wrapper adds any logic beyond forwarding
1950
+ - Flag pure proxies
1951
+
1952
+ 3. **Middleware without transformation**
1953
+ - Look for middleware/interceptor patterns
1954
+ - Check if they modify data or just pass through
1955
+ - Flag pass-through middleware
1956
+
1957
+ ## Output Format
1958
+
1959
+ For each over-abstraction found, create an idea file in \`.dust/ideas/\` with:
1960
+
1961
+ \`\`\`markdown
1962
+ # Over-Abstraction: [Type] in [Location]
1963
+
1964
+ ## Type
1965
+
1966
+ [Single-use | Deep hierarchy | Premature generalization | Excessive indirection]
1967
+
1968
+ ## Location
1969
+
1970
+ \`\`\`
1971
+ [file path]:[line number]
1972
+ \`\`\`
1973
+
1974
+ ## Description
1975
+
1976
+ [What the abstraction is]
1977
+
1978
+ ## Problem
1979
+
1980
+ [Why this is over-abstraction - complexity without benefit]
1981
+
1982
+ ## Usage Analysis
1983
+
1984
+ - **Times used**: [count]
1985
+ - **Variation in usage**: [how different are the use cases]
1986
+ - **Complexity cost**: [lines of code, indirection levels, etc.]
1987
+
1988
+ ## Suggested Simplification
1989
+
1990
+ [How to remove or reduce this abstraction]
1991
+
1992
+ ## Impact
1993
+
1994
+ [Lines of code saved, reduced complexity, improved clarity]
1995
+ \`\`\`
1996
+
1997
+ ## Special Considerations
1998
+
1999
+ 1. **Framework conventions** - Don't flag patterns mandated by frameworks:
2000
+ - React: Component base classes, hooks patterns
2001
+ - Express: Middleware signatures
2002
+ - Testing: Test base classes, fixture patterns
2003
+
2004
+ 2. **Library boundaries** - Public API abstractions may be justified even if internal usage is simple
2005
+
2006
+ 3. **Test code** - Apply the same standards to test code as production code
2007
+
2008
+ 4. **Context depth thresholds**:
2009
+ - Deep hierarchies (>2 levels) make understanding difficult
2010
+ - Wrapper chains (>2 levels) obscure actual behavior
2011
+ - Generic parameters should have multiple concrete usages
2012
+
2013
+ ## Blocked By
2014
+
2015
+ (none)
2016
+
2017
+ ## Definition of Done
2018
+
2019
+ - Searched for single-use interfaces, base classes, and utility functions
2020
+ - Identified deep inheritance hierarchies (>2 levels)
2021
+ - Found parameters always used with the same value
2022
+ - Detected unused configuration options
2023
+ - Located excessive wrapper chains and delegation
2024
+ - Respected framework conventions (didn't flag framework-mandated patterns)
2025
+ - Created idea files for each over-abstraction found
2026
+ - Each idea includes usage analysis and simplification suggestions
2027
+ - No changes to files outside \`.dust/\`
2028
+ `;
2029
+ }
1868
2030
  function primitiveObsession() {
1869
2031
  return dedent`
1870
2032
  # Primitive Obsession
@@ -3240,6 +3402,7 @@ var stockAuditFunctions = {
3240
3402
  "idiomatic-style": idiomaticStyle,
3241
3403
  "incidental-test-details": incidentalTestDetails,
3242
3404
  "logging-and-traceability": loggingAndTraceability,
3405
+ "over-abstraction": overAbstraction,
3243
3406
  "primitive-obsession": primitiveObsession,
3244
3407
  "repository-context": repositoryContext,
3245
3408
  "security-review": securityReview,
package/dist/dust.js CHANGED
@@ -7,7 +7,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
7
7
  var require_package = __commonJS((exports, module) => {
8
8
  module.exports = {
9
9
  name: "@joshski/dust",
10
- version: "0.1.109",
10
+ version: "0.1.110",
11
11
  description: "Flow state for AI coding agents",
12
12
  type: "module",
13
13
  bin: {
@@ -721,7 +721,7 @@ async function loadSettings(cwd, fileSystem, runtime) {
721
721
  }
722
722
 
723
723
  // lib/version.ts
724
- var DUST_VERSION = "0.1.109";
724
+ var DUST_VERSION = "0.1.110";
725
725
 
726
726
  // lib/cli/middleware.ts
727
727
  function applyMiddleware(middlewares, execute) {
@@ -2895,6 +2895,168 @@ function slowTests() {
2895
2895
  - No changes to files outside \`.dust/\`
2896
2896
  `;
2897
2897
  }
2898
+ function overAbstraction() {
2899
+ return dedent`
2900
+ # Over-Abstraction
2901
+
2902
+ Identify violations of the "reasonably-dry" principle where code has been over-engineered with excessive abstraction.
2903
+
2904
+ ${ideasHint}
2905
+
2906
+ ## Scope
2907
+
2908
+ Detect these over-abstraction patterns:
2909
+
2910
+ 1. **Single-use abstractions** - Interfaces, base classes, or utility functions used in only one place
2911
+ 2. **Deep inheritance hierarchies** - Classes extending more than 2 levels deep
2912
+ 3. **Premature generalization** - Parameters always used with the same value, unused options/flags
2913
+ 4. **Excessive indirection** - Multiple layers of wrappers adding no value
2914
+
2915
+ ## Analysis Steps
2916
+
2917
+ ### 1. Find Single-Use Abstractions
2918
+
2919
+ Search for abstractions that are only used once:
2920
+
2921
+ 1. **Interfaces with one implementation**
2922
+ - Search for \`interface\` declarations
2923
+ - Check if each interface has only one implementing class
2924
+ - Flag interfaces that exist solely for testing (can be replaced with the concrete type)
2925
+
2926
+ 2. **Base classes with one subclass**
2927
+ - Search for \`abstract class\` or classes used as base classes
2928
+ - Count implementations extending each base class
2929
+ - Flag base classes with only one subclass
2930
+
2931
+ 3. **Utility functions called once**
2932
+ - Search for exported utility functions
2933
+ - Check call sites - if only called from one location, it's over-abstraction
2934
+ - Consider inlining single-use utilities
2935
+
2936
+ 4. **Generic types with one concrete usage**
2937
+ - Find generic type parameters: \`<T>\`, \`<TData>\`, etc.
2938
+ - Check if T is always the same type at all call sites
2939
+ - Flag generics that could be concrete types
2940
+
2941
+ ### 2. Detect Deep Inheritance Hierarchies
2942
+
2943
+ Find inheritance chains longer than 2 levels:
2944
+
2945
+ 1. Search for \`extends\` keywords in class declarations
2946
+ 2. Build inheritance tree for each class
2947
+ 3. Flag chains deeper than 2 (A extends B extends C extends D...)
2948
+ 4. Respect framework conventions (don't flag React.Component, etc.)
2949
+
2950
+ ### 3. Identify Premature Generalization
2951
+
2952
+ Look for flexibility that's never used:
2953
+
2954
+ 1. **Always-same parameter values**
2955
+ - Find function parameters
2956
+ - Check all call sites - if always the same value, it's not needed
2957
+ - Flag parameters that could be constants or removed
2958
+
2959
+ 2. **Unused configuration options**
2960
+ - Search for configuration objects/interfaces
2961
+ - Check which options are actually used
2962
+ - Flag options that are never set or always default
2963
+
2964
+ 3. **Unused function parameters**
2965
+ - Find parameters that aren't referenced in function bodies
2966
+ - Flag as candidates for removal
2967
+
2968
+ ### 4. Find Excessive Indirection
2969
+
2970
+ Detect wrapper chains that add no value:
2971
+
2972
+ 1. **Delegation chains**
2973
+ - Search for functions that only call another function
2974
+ - Flag wrappers that don't add logic, just forward calls
2975
+ - Example: \`function foo(x) { return bar(x) }\`
2976
+
2977
+ 2. **Proxy patterns without behavior**
2978
+ - Find classes that wrap another class
2979
+ - Check if wrapper adds any logic beyond forwarding
2980
+ - Flag pure proxies
2981
+
2982
+ 3. **Middleware without transformation**
2983
+ - Look for middleware/interceptor patterns
2984
+ - Check if they modify data or just pass through
2985
+ - Flag pass-through middleware
2986
+
2987
+ ## Output Format
2988
+
2989
+ For each over-abstraction found, create an idea file in \`.dust/ideas/\` with:
2990
+
2991
+ \`\`\`markdown
2992
+ # Over-Abstraction: [Type] in [Location]
2993
+
2994
+ ## Type
2995
+
2996
+ [Single-use | Deep hierarchy | Premature generalization | Excessive indirection]
2997
+
2998
+ ## Location
2999
+
3000
+ \`\`\`
3001
+ [file path]:[line number]
3002
+ \`\`\`
3003
+
3004
+ ## Description
3005
+
3006
+ [What the abstraction is]
3007
+
3008
+ ## Problem
3009
+
3010
+ [Why this is over-abstraction - complexity without benefit]
3011
+
3012
+ ## Usage Analysis
3013
+
3014
+ - **Times used**: [count]
3015
+ - **Variation in usage**: [how different are the use cases]
3016
+ - **Complexity cost**: [lines of code, indirection levels, etc.]
3017
+
3018
+ ## Suggested Simplification
3019
+
3020
+ [How to remove or reduce this abstraction]
3021
+
3022
+ ## Impact
3023
+
3024
+ [Lines of code saved, reduced complexity, improved clarity]
3025
+ \`\`\`
3026
+
3027
+ ## Special Considerations
3028
+
3029
+ 1. **Framework conventions** - Don't flag patterns mandated by frameworks:
3030
+ - React: Component base classes, hooks patterns
3031
+ - Express: Middleware signatures
3032
+ - Testing: Test base classes, fixture patterns
3033
+
3034
+ 2. **Library boundaries** - Public API abstractions may be justified even if internal usage is simple
3035
+
3036
+ 3. **Test code** - Apply the same standards to test code as production code
3037
+
3038
+ 4. **Context depth thresholds**:
3039
+ - Deep hierarchies (>2 levels) make understanding difficult
3040
+ - Wrapper chains (>2 levels) obscure actual behavior
3041
+ - Generic parameters should have multiple concrete usages
3042
+
3043
+ ## Blocked By
3044
+
3045
+ (none)
3046
+
3047
+ ## Definition of Done
3048
+
3049
+ - Searched for single-use interfaces, base classes, and utility functions
3050
+ - Identified deep inheritance hierarchies (>2 levels)
3051
+ - Found parameters always used with the same value
3052
+ - Detected unused configuration options
3053
+ - Located excessive wrapper chains and delegation
3054
+ - Respected framework conventions (didn't flag framework-mandated patterns)
3055
+ - Created idea files for each over-abstraction found
3056
+ - Each idea includes usage analysis and simplification suggestions
3057
+ - No changes to files outside \`.dust/\`
3058
+ `;
3059
+ }
2898
3060
  function primitiveObsession() {
2899
3061
  return dedent`
2900
3062
  # Primitive Obsession
@@ -4270,6 +4432,7 @@ var stockAuditFunctions = {
4270
4432
  "idiomatic-style": idiomaticStyle,
4271
4433
  "incidental-test-details": incidentalTestDetails,
4272
4434
  "logging-and-traceability": loggingAndTraceability,
4435
+ "over-abstraction": overAbstraction,
4273
4436
  "primitive-obsession": primitiveObsession,
4274
4437
  "repository-context": repositoryContext,
4275
4438
  "security-review": securityReview,
@@ -5754,6 +5917,8 @@ function buildImplementationInstructions(bin, hooksInstalled, taskTitle, taskPat
5754
5917
  steps.push(`${step}. Run \`${bin} check\` to verify the project is in a good state`);
5755
5918
  step++;
5756
5919
  }
5920
+ steps.push(`${step}. If the task file contains Principles and Guidance sections, read and follow them before implementing changes`);
5921
+ step++;
5757
5922
  steps.push(`${step}. Implement the task`);
5758
5923
  step++;
5759
5924
  if (!hooksInstalled) {
package/dist/patch.js CHANGED
@@ -167,7 +167,7 @@ function isErrorCode(error, code) {
167
167
  }
168
168
 
169
169
  // lib/validation/index.ts
170
- import { relative } from "node:path";
170
+ import { relative, resolve as resolve3 } from "node:path";
171
171
 
172
172
  // lib/validation/overlay-filesystem.ts
173
173
  function createOverlayFileSystem(base, patchFiles, deletedPaths = new Set) {
@@ -1003,11 +1003,12 @@ function parsePatchFiles(dustPath, patch) {
1003
1003
  }
1004
1004
  async function validatePatch(fileSystem, dustPath, patch, options = {}) {
1005
1005
  const cwd = options.cwd ?? process.cwd();
1006
- const { absolutePatchFiles, deletedPaths } = parsePatchFiles(dustPath, patch);
1006
+ const resolvedDustPath = resolve3(dustPath);
1007
+ const { absolutePatchFiles, deletedPaths } = parsePatchFiles(resolvedDustPath, patch);
1007
1008
  const overlayFs = createOverlayFileSystem(fileSystem, absolutePatchFiles, deletedPaths);
1008
1009
  const violations = [];
1009
- violations.push(...validatePatchRootEntries(fileSystem, dustPath, patch));
1010
- const { context, violations: parseViolations } = await parseArtifacts(overlayFs, dustPath);
1010
+ violations.push(...validatePatchRootEntries(fileSystem, resolvedDustPath, patch));
1011
+ const { context, violations: parseViolations } = await parseArtifacts(overlayFs, resolvedDustPath);
1011
1012
  violations.push(...parseViolations);
1012
1013
  violations.push(...validateArtifacts(context));
1013
1014
  return {
@@ -1,5 +1,5 @@
1
1
  // lib/validation/index.ts
2
- import { relative } from "node:path";
2
+ import { relative, resolve as resolve3 } from "node:path";
3
3
 
4
4
  // lib/filesystem/error-codes.ts
5
5
  function isErrnoException(error) {
@@ -1000,11 +1000,12 @@ function parsePatchFiles(dustPath, patch) {
1000
1000
  }
1001
1001
  async function validatePatch(fileSystem, dustPath, patch, options = {}) {
1002
1002
  const cwd = options.cwd ?? process.cwd();
1003
- const { absolutePatchFiles, deletedPaths } = parsePatchFiles(dustPath, patch);
1003
+ const resolvedDustPath = resolve3(dustPath);
1004
+ const { absolutePatchFiles, deletedPaths } = parsePatchFiles(resolvedDustPath, patch);
1004
1005
  const overlayFs = createOverlayFileSystem(fileSystem, absolutePatchFiles, deletedPaths);
1005
1006
  const violations = [];
1006
- violations.push(...validatePatchRootEntries(fileSystem, dustPath, patch));
1007
- const { context, violations: parseViolations } = await parseArtifacts(overlayFs, dustPath);
1007
+ violations.push(...validatePatchRootEntries(fileSystem, resolvedDustPath, patch));
1008
+ const { context, violations: parseViolations } = await parseArtifacts(overlayFs, resolvedDustPath);
1008
1009
  violations.push(...parseViolations);
1009
1010
  violations.push(...validateArtifacts(context));
1010
1011
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@joshski/dust",
3
- "version": "0.1.109",
3
+ "version": "0.1.110",
4
4
  "description": "Flow state for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {