@difflab/difflab-cli 0.10.0 → 0.11.0
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/README.md +3 -1
- package/dist/index.js +201 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,7 +66,9 @@ difflab-cli templates list
|
|
|
66
66
|
difflab-cli templates scaffold spec-driven-plan docs/plans first-plan.md --cwd /absolute/project/path
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
The CLI defaults `--cwd` to its current directory. The MCP server exposes `template_list({})` and `scaffold({"name":"spec-driven-plan","cwd":"/absolute/project/path","path":"docs/plans","filename":"first-plan.md"})`. Both interfaces take a hyphenated template name, a relative destination **directory** (`path`, or `.` for `cwd`), and a separate **filename**. MCP always requires an absolute existing `cwd`. Missing destination directories are created. Available names: `spec-driven-plan`, `software-architecture-design`, `architecture-decision-record`, `product-requirements-document`, `agents`, `code-review`, `planning-intent`, `ui-component-architecture`, `pull-request-description` (adapted from Diffpi's PR template), `flow-definition`, `flow-instance`, `exploration-summary`, `exploration-research`, `exploration-proposal`, and `poc-readme`.
|
|
69
|
+
The CLI defaults `--cwd` to its current directory. The MCP server exposes `template_list({})` and `scaffold({"name":"spec-driven-plan","cwd":"/absolute/project/path","path":"docs/plans","filename":"first-plan.md"})`. Both interfaces take a hyphenated template name, a relative destination **directory** (`path`, or `.` for `cwd`), and a separate **filename**. MCP always requires an absolute existing `cwd`. Missing destination directories are created. Available names: `spec-driven-plan`, `software-architecture-design`, `architecture-decision-record`, `product-requirements-document`, `agents`, `code-review`, `code-review-rubric`, `planning-intent`, `ui-component-architecture`, `pull-request-description` (adapted from Diffpi's PR template), `flow-definition`, `flow-instance`, `exploration-summary`, `exploration-research`, `exploration-proposal`, and `poc-readme`.
|
|
70
|
+
|
|
71
|
+
Reviews scaffold `code-review` as `REVIEW.md` and `code-review-rubric` as `rubric.yaml` in `.difflab/reviews/YYMMDD-name`. The installed rubric is `~/.difflab/templates/code-review-rubric.yaml`. Fill its criterion results during the review. File-scoped criteria require a path-tagged result for every changed source file. Function findings can include `file:line` locations. Evidence guidance and review instructions stay in the review skill, outside the lean YAML template.
|
|
70
72
|
|
|
71
73
|
Use `difflab-cli templates scaffold agents . AGENTS.md --cwd /absolute/project/path` to start repository guidance. Fill the prompts with known rules and remove unused prompts. The template separates Hard Rules, Organization, Style, and Testing. Hard Rules name required task runners and repository tools. Organization separates directory layout from section headers, code ordering, and grouping within files. Review addressing saves explicit user repository rules immediately and marks inferred or uncertain rules with `[Proposed]`. It asks before reorganizing existing guidance to match the template and adapts the existing structure if permission is declined. It retains terse file-level organization rules and keeps guidance within 500 soft-wrapped source lines.
|
|
72
74
|
|
package/dist/index.js
CHANGED
|
@@ -48664,6 +48664,8 @@ var code_review_default = `# Review: [change or pull request]
|
|
|
48664
48664
|
- **Intent:** [stated objective and source]
|
|
48665
48665
|
- **Reviewer:** [name]
|
|
48666
48666
|
|
|
48667
|
+
[Apply root and applicable nested AGENTS.md rules throughout every section. Repository rules take precedence over generic rubric conventions. Cite violations under the relevant section.]
|
|
48668
|
+
|
|
48667
48669
|
## Intent Delivery
|
|
48668
48670
|
|
|
48669
48671
|
[Does the change actually deliver the intended behavior? What is missing or outside scope?]
|
|
@@ -48674,7 +48676,7 @@ var code_review_default = `# Review: [change or pull request]
|
|
|
48674
48676
|
|
|
48675
48677
|
## Semantic Organization
|
|
48676
48678
|
|
|
48677
|
-
[Do modules have clear roles and useful public APIs? Identify mixed responsibilities and unclear ownership. Refactor or simplify at the scope needed to make the change understandable, including across files. Keep unrelated work out of scope.]
|
|
48679
|
+
[Do modules have clear roles and useful public APIs? Are exported types meaningful for the module role? Are methods and classes easy to discover and use? Identify mixed responsibilities and unclear ownership. Refactor or simplify at the scope needed to make the change understandable, including across files. Keep unrelated work out of scope.]
|
|
48678
48680
|
|
|
48679
48681
|
## Maintainability
|
|
48680
48682
|
|
|
@@ -48682,11 +48684,11 @@ var code_review_default = `# Review: [change or pull request]
|
|
|
48682
48684
|
|
|
48683
48685
|
## Reliability/Testing
|
|
48684
48686
|
|
|
48685
|
-
[Prioritize end-to-end application behavior, then module behavior through public APIs, then focused unit behavior with public APIs first. Name missing observable contracts or regressions; do not demand coverage of every function or a percentage. Check semantic grouping, clear Arrange/Act/Assert blocks, fixtures, and existing shared helpers. Flag walls of repeated setup or interleaved actions/assertions that hide the behavior. Report executed checks and limits honestly.]
|
|
48687
|
+
[Prioritize end-to-end application behavior, then module behavior through public APIs, then focused unit behavior with public APIs first. Flag tests that only verify external dependencies rather than the repository's source behavior or integration contract. Require test names to identify the function or functionality tested and its expected behavior, regardless of grouping style. Name missing observable contracts or regressions; do not demand coverage of every function or a percentage. Check semantic grouping, clear Arrange/Act/Assert blocks, fixtures, and existing shared helpers. Flag walls of repeated setup or interleaved actions/assertions that hide the behavior. Report executed checks and limits honestly.]
|
|
48686
48688
|
|
|
48687
|
-
##
|
|
48689
|
+
## Documentation
|
|
48688
48690
|
|
|
48689
|
-
[
|
|
48691
|
+
[Flag walls of text, complex language, and text that only restates the implementation. Require concise, simple-English explanations. Prefer diagrams when they clarify structures, flows, or relationships better than long prose.]
|
|
48690
48692
|
|
|
48691
48693
|
## Performance
|
|
48692
48694
|
|
|
@@ -48694,11 +48696,11 @@ var code_review_default = `# Review: [change or pull request]
|
|
|
48694
48696
|
|
|
48695
48697
|
## Security
|
|
48696
48698
|
|
|
48697
|
-
[
|
|
48699
|
+
[Optional: run this dimension only when explicitly requested, including a security focus. Otherwise state that it was not selected. Report clear security defects discovered by other dimensions without claiming a security audit. Avoid unrelated hardening requests.]
|
|
48698
48700
|
|
|
48699
48701
|
## Change Requests
|
|
48700
48702
|
|
|
48701
|
-
|
|
48703
|
+
Every generated comment and reply must use simple English and be as short as possible. Include a suggested change when a concrete fix is available. State the issue and its effect directly. Phrase recommendations with \u201CLet's\u201D, \u201CI suggest\u201D, or \u201CI recommend\u201D. Include a short snippet or suggested patch only when it clarifies the fix. Use the scope that fixes the problem, including a refactor when needed. Group repeated instances of one cause. Omit repeated context, nitpicks, minor optimizations, and speculative findings. End each generated request and response with its model attribution quote. Preserve human text unchanged.
|
|
48702
48704
|
|
|
48703
48705
|
### [file:line \u2014 request]
|
|
48704
48706
|
|
|
@@ -48724,10 +48726,185 @@ Use short comments in simple English. State the problem and its effect directly.
|
|
|
48724
48726
|
## Verification and Limits
|
|
48725
48727
|
|
|
48726
48728
|
- **Checks run:** [command and result.]
|
|
48727
|
-
- **Not verified:** [environment, path, or
|
|
48729
|
+
- **Not verified:** [environment, path, behavior, or applicable repository guidance that could not be checked.]
|
|
48730
|
+
- **Rubric:** [path to the copied YAML rubric with completed criterion results. Disclose missing, pending, skipped, or stale results.]
|
|
48728
48731
|
`;
|
|
48729
48732
|
var init_code_review = () => {};
|
|
48730
48733
|
|
|
48734
|
+
// templates/code-review-rubric.yaml
|
|
48735
|
+
var code_review_rubric_default = `version: 1
|
|
48736
|
+
worker_defaults:
|
|
48737
|
+
model: sol
|
|
48738
|
+
reasoning_effort: medium
|
|
48739
|
+
review:
|
|
48740
|
+
base_revision: null
|
|
48741
|
+
head_revision: null
|
|
48742
|
+
working_tree: null
|
|
48743
|
+
changed_files: []
|
|
48744
|
+
exclusions: []
|
|
48745
|
+
section_reviewers: []
|
|
48746
|
+
sections:
|
|
48747
|
+
- title: Intent Delivery
|
|
48748
|
+
criteria:
|
|
48749
|
+
- id: intent.objective
|
|
48750
|
+
scope: review
|
|
48751
|
+
default_severity: blocking
|
|
48752
|
+
issue: The change contradicts its stated intent or omits required behavior.
|
|
48753
|
+
results: []
|
|
48754
|
+
- id: intent.scope
|
|
48755
|
+
scope: review
|
|
48756
|
+
default_severity: consider
|
|
48757
|
+
issue: The change includes work outside its stated scope.
|
|
48758
|
+
results: []
|
|
48759
|
+
- title: Readability
|
|
48760
|
+
criteria:
|
|
48761
|
+
- id: readability.function-names
|
|
48762
|
+
scope: file
|
|
48763
|
+
default_severity: consider
|
|
48764
|
+
issue: >-
|
|
48765
|
+
Function or other names misrepresent behavior, hide side effects, or break established naming conventions.
|
|
48766
|
+
results: []
|
|
48767
|
+
- id: readability.structure
|
|
48768
|
+
scope: file
|
|
48769
|
+
default_severity: consider
|
|
48770
|
+
issue: The changed flow is materially hard to follow.
|
|
48771
|
+
results: []
|
|
48772
|
+
- title: Semantic Organization
|
|
48773
|
+
criteria:
|
|
48774
|
+
- id: organization.roles
|
|
48775
|
+
scope: file
|
|
48776
|
+
default_severity: consider
|
|
48777
|
+
issue: A module mixes responsibilities or its imports, exports, or public API obscure its role.
|
|
48778
|
+
results: []
|
|
48779
|
+
- id: organization.architecture
|
|
48780
|
+
scope: review
|
|
48781
|
+
default_severity: consider
|
|
48782
|
+
issue: Files or classes break the established architecture or module patterns.
|
|
48783
|
+
results: []
|
|
48784
|
+
- id: organization.api-ergonomics
|
|
48785
|
+
scope: applicable-file
|
|
48786
|
+
applies_when: Added or modified public APIs, exported types, methods, or classes.
|
|
48787
|
+
default_severity: consider
|
|
48788
|
+
issue: Public APIs expose types unrelated to the module role or are hard to discover and use.
|
|
48789
|
+
results: []
|
|
48790
|
+
- id: organization.new-files
|
|
48791
|
+
scope: applicable-file
|
|
48792
|
+
applies_when: Added source files that introduce a module or submodule. A rename alone does not qualify.
|
|
48793
|
+
default_severity: consider
|
|
48794
|
+
issue: >-
|
|
48795
|
+
A new file lacks a justified module boundary or contains functions that belong in an existing module.
|
|
48796
|
+
results: []
|
|
48797
|
+
- id: organization.file-structure
|
|
48798
|
+
scope: file
|
|
48799
|
+
default_severity: consider
|
|
48800
|
+
issue: A file breaks the project-prescribed structure or declaration order.
|
|
48801
|
+
results: []
|
|
48802
|
+
- title: Maintainability
|
|
48803
|
+
criteria:
|
|
48804
|
+
- id: maintainability.concepts
|
|
48805
|
+
scope: review
|
|
48806
|
+
default_severity: consider
|
|
48807
|
+
issue: >-
|
|
48808
|
+
New fields, types, wrappers, helpers, dependencies, or layers lack a justified use and add needless complexity.
|
|
48809
|
+
results: []
|
|
48810
|
+
- id: maintainability.complexity
|
|
48811
|
+
scope: applicable-file
|
|
48812
|
+
applies_when: >-
|
|
48813
|
+
Files with added or changed executable functions. For new functions, assess whether the introduced decision paths are justified.
|
|
48814
|
+
default_severity: consider
|
|
48815
|
+
issue: Cyclomatic complexity grows without justification from the required behavior.
|
|
48816
|
+
results: []
|
|
48817
|
+
- id: maintainability.utilities
|
|
48818
|
+
scope: review
|
|
48819
|
+
default_severity: consider
|
|
48820
|
+
issue: Duplicated state or behavior, or inline work, makes a function harder to read or maintain.
|
|
48821
|
+
results: []
|
|
48822
|
+
- id: maintainability.packages
|
|
48823
|
+
scope: review
|
|
48824
|
+
default_severity: consider
|
|
48825
|
+
issue: >-
|
|
48826
|
+
Custom code recreates functionality that an established, widely used package suitably provides.
|
|
48827
|
+
results: []
|
|
48828
|
+
- title: Reliability/Testing
|
|
48829
|
+
criteria:
|
|
48830
|
+
- id: testing.correctness
|
|
48831
|
+
scope: file
|
|
48832
|
+
default_severity: blocking
|
|
48833
|
+
issue: The changed code produces incorrect behavior.
|
|
48834
|
+
results: []
|
|
48835
|
+
- id: testing.application
|
|
48836
|
+
scope: review
|
|
48837
|
+
default_severity: consider
|
|
48838
|
+
issue: Required behavior or a meaningful regression lacks test evidence.
|
|
48839
|
+
results: []
|
|
48840
|
+
- id: testing.relevance
|
|
48841
|
+
scope: applicable-file
|
|
48842
|
+
applies_when: Added or modified test files.
|
|
48843
|
+
default_severity: consider
|
|
48844
|
+
issue: >-
|
|
48845
|
+
A test verifies external dependency behavior without establishing behavior of the repository's own source code.
|
|
48846
|
+
results: []
|
|
48847
|
+
- id: testing.names
|
|
48848
|
+
scope: applicable-file
|
|
48849
|
+
applies_when: Added or modified test files.
|
|
48850
|
+
default_severity: consider
|
|
48851
|
+
issue: >-
|
|
48852
|
+
A test name does not identify the function or functionality tested and its expected behavior.
|
|
48853
|
+
results: []
|
|
48854
|
+
- id: testing.arrange-act-assert
|
|
48855
|
+
scope: applicable-file
|
|
48856
|
+
applies_when: Added or modified test files.
|
|
48857
|
+
default_severity: consider
|
|
48858
|
+
issue: >-
|
|
48859
|
+
Test grouping or interleaved setup, actions, and assertions hide the scenario or expected result.
|
|
48860
|
+
results: []
|
|
48861
|
+
- id: testing.fixtures
|
|
48862
|
+
scope: applicable-file
|
|
48863
|
+
applies_when: Added or modified tests, fixtures, test setup, or test utility files.
|
|
48864
|
+
default_severity: consider
|
|
48865
|
+
issue: >-
|
|
48866
|
+
Repeated setup, unsuitable fixtures, or recreated shared utilities obscure tests or duplicate existing helpers.
|
|
48867
|
+
results: []
|
|
48868
|
+
- title: Documentation
|
|
48869
|
+
criteria:
|
|
48870
|
+
- id: documentation.conciseness
|
|
48871
|
+
scope: applicable-file
|
|
48872
|
+
applies_when: Added or modified documentation, including documentation comments.
|
|
48873
|
+
default_severity: consider
|
|
48874
|
+
issue: Long, dense, or complex text makes documentation hard to understand.
|
|
48875
|
+
results: []
|
|
48876
|
+
- id: documentation.redundancy
|
|
48877
|
+
scope: applicable-file
|
|
48878
|
+
applies_when: Added or modified documentation, including documentation comments.
|
|
48879
|
+
default_severity: consider
|
|
48880
|
+
issue: Documentation repeats the implementation or other text without adding useful context.
|
|
48881
|
+
results: []
|
|
48882
|
+
- id: documentation.visuals
|
|
48883
|
+
scope: applicable-file
|
|
48884
|
+
applies_when: Added or modified documentation that explains structures, flows, or relationships.
|
|
48885
|
+
default_severity: consider
|
|
48886
|
+
issue: A long textual explanation obscures information that a diagram would make clearer.
|
|
48887
|
+
results: []
|
|
48888
|
+
- title: Performance
|
|
48889
|
+
criteria:
|
|
48890
|
+
- id: performance.regressions
|
|
48891
|
+
scope: review
|
|
48892
|
+
default_severity: consider
|
|
48893
|
+
issue: The change causes a material performance regression.
|
|
48894
|
+
results: []
|
|
48895
|
+
- title: Security
|
|
48896
|
+
optional: true
|
|
48897
|
+
criteria:
|
|
48898
|
+
- id: security.defects
|
|
48899
|
+
scope: review
|
|
48900
|
+
default_severity: blocking
|
|
48901
|
+
issue: The change exposes secrets or breaks authorization or a trust boundary.
|
|
48902
|
+
results: []
|
|
48903
|
+
worker:
|
|
48904
|
+
reasoning_effort: high
|
|
48905
|
+
`;
|
|
48906
|
+
var init_code_review_rubric = () => {};
|
|
48907
|
+
|
|
48731
48908
|
// templates/planning-intent.md
|
|
48732
48909
|
var planning_intent_default = `# Intent: [short name]
|
|
48733
48910
|
|
|
@@ -49748,6 +49925,7 @@ var init_source = __esm(() => {
|
|
|
49748
49925
|
init_product_requirements_document();
|
|
49749
49926
|
init_agents();
|
|
49750
49927
|
init_code_review();
|
|
49928
|
+
init_code_review_rubric();
|
|
49751
49929
|
init_planning_intent();
|
|
49752
49930
|
init_ui_component_architecture();
|
|
49753
49931
|
init_pull_request_description();
|
|
@@ -49774,6 +49952,7 @@ var init_source = __esm(() => {
|
|
|
49774
49952
|
"product-requirements-document.md": product_requirements_document_default,
|
|
49775
49953
|
"agents.md": agents_default,
|
|
49776
49954
|
"code-review.md": code_review_default,
|
|
49955
|
+
"code-review-rubric.yaml": code_review_rubric_default,
|
|
49777
49956
|
"planning-intent.md": planning_intent_default,
|
|
49778
49957
|
"ui-component-architecture.md": ui_component_architecture_default,
|
|
49779
49958
|
"pull-request-description.md": pull_request_description_default,
|
|
@@ -49801,6 +49980,11 @@ var init_source = __esm(() => {
|
|
|
49801
49980
|
{ name: "product-requirements-document", description: "Product requirements document" },
|
|
49802
49981
|
{ name: "agents", description: "Concise repository rules for AGENTS.md" },
|
|
49803
49982
|
{ name: "code-review", description: "Thorough code review" },
|
|
49983
|
+
{
|
|
49984
|
+
name: "code-review-rubric",
|
|
49985
|
+
description: "YAML code review criteria and per-file results",
|
|
49986
|
+
asset: "code-review-rubric.yaml"
|
|
49987
|
+
},
|
|
49804
49988
|
{ name: "planning-intent", description: "Planning intent for a user to fill in" },
|
|
49805
49989
|
{ name: "ui-component-architecture", description: "UI component design and implementation" },
|
|
49806
49990
|
{ name: "pull-request-description", description: "Draft pull request description" },
|
|
@@ -49844,7 +50028,8 @@ class TemplateService {
|
|
|
49844
50028
|
return [...this.source.catalog];
|
|
49845
50029
|
}
|
|
49846
50030
|
async scaffoldFromTemplate(name, cwd, path, filename) {
|
|
49847
|
-
|
|
50031
|
+
const template = this.source.catalog.find((item) => item.name === name);
|
|
50032
|
+
if (!template) {
|
|
49848
50033
|
throw new UnknownTemplateError(`Unknown template: ${name}`);
|
|
49849
50034
|
}
|
|
49850
50035
|
if (!path.trim() || isAbsolute7(path)) {
|
|
@@ -49854,8 +50039,8 @@ class TemplateService {
|
|
|
49854
50039
|
throw new TemplateError("filename must be a single non-empty file name");
|
|
49855
50040
|
}
|
|
49856
50041
|
await this.installMissing();
|
|
49857
|
-
const installed = await resolvePath(this.home, join6(".difflab", "templates", `${name}.md`));
|
|
49858
|
-
const contents = await
|
|
50042
|
+
const installed = await resolvePath(this.home, join6(".difflab", "templates", template.asset ?? `${name}.md`));
|
|
50043
|
+
const contents = await readTemplate(installed);
|
|
49859
50044
|
const destination = path.startsWith(".difflab/") ? await this.projectDestination(cwd, path.slice(".difflab/".length), filename) : await ensurePathDirsExist(join6(path, filename), cwd);
|
|
49860
50045
|
try {
|
|
49861
50046
|
await createExclusive(destination, contents);
|
|
@@ -49888,7 +50073,7 @@ class TemplateService {
|
|
|
49888
50073
|
if ((await lstat7(destination)).isSymbolicLink()) {
|
|
49889
50074
|
throw new TemplateSourceError(`Installed template asset is a symlink: ${destination}`);
|
|
49890
50075
|
}
|
|
49891
|
-
await
|
|
50076
|
+
await readTemplate(destination);
|
|
49892
50077
|
} catch (error) {
|
|
49893
50078
|
if (!hasErrorCode(error, "ENOENT"))
|
|
49894
50079
|
throw error;
|
|
@@ -49898,7 +50083,7 @@ class TemplateService {
|
|
|
49898
50083
|
} catch (writeError) {
|
|
49899
50084
|
if (!hasErrorCode(writeError, "EEXIST"))
|
|
49900
50085
|
throw writeError;
|
|
49901
|
-
await
|
|
50086
|
+
await readTemplate(destination);
|
|
49902
50087
|
}
|
|
49903
50088
|
}
|
|
49904
50089
|
}
|
|
@@ -49916,7 +50101,7 @@ async function readSource(source, asset) {
|
|
|
49916
50101
|
throw new TemplateSourceError(`Cannot read template asset: ${asset}`, { cause: error });
|
|
49917
50102
|
}
|
|
49918
50103
|
}
|
|
49919
|
-
async function
|
|
50104
|
+
async function readTemplate(path) {
|
|
49920
50105
|
let handle;
|
|
49921
50106
|
try {
|
|
49922
50107
|
handle = await open3(path, constants2.O_RDONLY | constants2.O_NOFOLLOW);
|
|
@@ -49974,7 +50159,8 @@ var init_tools4 = __esm(() => {
|
|
|
49974
50159
|
init_service();
|
|
49975
50160
|
templateInfo = object({
|
|
49976
50161
|
name: string2(),
|
|
49977
|
-
description: string2()
|
|
50162
|
+
description: string2(),
|
|
50163
|
+
asset: string2().optional()
|
|
49978
50164
|
});
|
|
49979
50165
|
templateListOutput = object({ result: array(templateInfo) });
|
|
49980
50166
|
scaffoldOutput = object({
|
|
@@ -52366,7 +52552,7 @@ function createProgram(write = console.log, version = "0.1.0", options = {}) {
|
|
|
52366
52552
|
|
|
52367
52553
|
// src/index.ts
|
|
52368
52554
|
init_errors3();
|
|
52369
|
-
var version2 = "0.
|
|
52555
|
+
var version2 = "0.11.0";
|
|
52370
52556
|
try {
|
|
52371
52557
|
await createProgram(console.log, version2).parseAsync(process.argv);
|
|
52372
52558
|
} catch (error) {
|