@namewta/speculo 0.3.4 → 0.5.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 +4 -5
- package/package.json +1 -1
- package/template/canonical/canonical-specdev-engineering-cognitive-mentor.md +5 -0
- package/template/canonical/canonical-specdev-goal-plan.md +366 -59
- package/template/canonical/canonical-specdev-grill-with-docs.md +153 -104
- package/template/canonical/canonical-specdev-spec.md +5 -0
- package/template/canonical/canonical-specdev-tickets.md +5 -0
- package/template/canonical/canonical-specdev-wayfinder.md +171 -249
- package/template/commands/docs-sync.md +3 -3
- package/template/skills/docs-sync/SKILL.md +4 -3
- package/template/skills/docs-sync/assets/report-template.md +1 -0
- package/template/skills/docs-sync/references/agents/agent-writing.md +75 -0
- package/template/skills/{agents-md-builder/references → docs-sync/references/agents}/claude-redirect.md +1 -1
- package/template/skills/docs-sync/references/agents-contract.md +23 -1
- package/template/skills/typescript-standards-builder/README.md +53 -0
- package/template/skills/typescript-standards-builder/SKILL.md +245 -0
- package/template/skills/typescript-standards-builder/examples/sample-generated-tree.md +30 -0
- package/template/skills/typescript-standards-builder/examples/sample-interview-decisions.md +26 -0
- package/template/skills/typescript-standards-builder/manifest.txt +29 -0
- package/template/skills/typescript-standards-builder/references/00-governance-and-fixed-defaults.md +77 -0
- package/template/skills/typescript-standards-builder/references/01-project-discovery.md +100 -0
- package/template/skills/typescript-standards-builder/references/02-interview-workflow.md +129 -0
- package/template/skills/typescript-standards-builder/references/03-project-architecture-and-directory-layout.md +84 -0
- package/template/skills/typescript-standards-builder/references/04-file-directory-and-symbol-naming.md +92 -0
- package/template/skills/typescript-standards-builder/references/05-modules-imports-exports-and-dependencies.md +63 -0
- package/template/skills/typescript-standards-builder/references/06-typescript-type-system.md +64 -0
- package/template/skills/typescript-standards-builder/references/07-functions-async-errors-and-resources.md +42 -0
- package/template/skills/typescript-standards-builder/references/08-comments-jsdoc-and-documentation.md +51 -0
- package/template/skills/typescript-standards-builder/references/09-testing-strategy.md +58 -0
- package/template/skills/typescript-standards-builder/references/10-react-and-frontend.md +39 -0
- package/template/skills/typescript-standards-builder/references/11-node-cli-and-cross-platform.md +31 -0
- package/template/skills/typescript-standards-builder/references/12-formatting-lint-and-complexity.md +58 -0
- package/template/skills/typescript-standards-builder/references/13-configuration-dependencies-and-ci.md +71 -0
- package/template/skills/typescript-standards-builder/references/14-security-performance-and-i18n.md +32 -0
- package/template/skills/typescript-standards-builder/references/15-git-review-and-delivery.md +28 -0
- package/template/skills/typescript-standards-builder/references/16-adoption-exceptions-and-migration.md +61 -0
- package/template/skills/typescript-standards-builder/references/17-generation-contract.md +104 -0
- package/template/skills/typescript-standards-builder/references/README.md +37 -0
- package/template/skills/typescript-standards-builder/templates/agents-compat-skill/SKILL.md +1 -0
- package/template/skills/typescript-standards-builder/templates/claude-skill/SKILL.md +1 -0
- package/template/skills/typescript-standards-builder/templates/project-skill/SKILL.md.template +34 -0
- package/template/skills/typescript-standards-builder/templates/project-skill/references/00-project-profile.md.template +17 -0
- package/template/skills/typescript-standards-builder/templates/project-skill/references/10-review-checklist.md +23 -0
- package/template/skills/typescript-standards-builder/templates/project-skill/references/11-decisions-and-exceptions.md.template +19 -0
- package/template/workflows/specdev/G-grill-with-docs/G-grill-with-docs.md +78 -73
- package/template/workflows/specdev/G-grill-with-docs/design-tree-template.json +9 -0
- package/template/workflows/specdev/G-grill-with-docs/grilling-protocol.md +16 -35
- package/template/workflows/specdev/G-grill-with-docs/log-format.md +2 -0
- package/template/workflows/specdev/I-implement/I-implement.md +12 -10
- package/template/workflows/specdev/I-implement/design-it-twice.md +45 -6
- package/template/workflows/specdev/I-implement/evidence-template.md +7 -0
- package/template/workflows/specdev/I-implement/execution-preflight.md +6 -0
- package/template/workflows/specdev/INDEX.md +11 -4
- package/template/workflows/specdev/P-goal-plan/P-goal-plan.md +23 -10
- package/template/workflows/specdev/P-goal-plan/completion-control.md +20 -7
- package/template/workflows/specdev/P-goal-plan/goal-plan-template.md +55 -3
- package/template/workflows/specdev/P-goal-plan/orchestration-protocol.md +42 -38
- package/template/workflows/specdev/P-goal-plan/planning-modes.md +36 -2
- package/template/workflows/specdev/R-review-architecture/R-review-architecture.md +67 -80
- package/template/workflows/specdev/R-review-architecture/architecture-report-contract.md +123 -0
- package/template/workflows/specdev/R-review-architecture/architecture-review-report-template.html +103 -55
- package/template/workflows/specdev/R-review-architecture/architecture-review-template.md +20 -29
- package/template/workflows/specdev/W-wayfinder/W-wayfinder.md +76 -147
- package/template/workflows/specdev/W-wayfinder/investigation-ticket-template.md +8 -53
- package/template/workflows/specdev/W-wayfinder/local-tracker-contract.md +36 -0
- package/template/workflows/specdev/W-wayfinder/solution-comment-template.md +17 -0
- package/template/workflows/specdev/W-wayfinder/wayfinder-map-template.md +12 -65
- package/template/workflows/specdev/common/README.md +4 -0
- package/template/workflows/specdev/common/rules/artifact-contract.md +5 -0
- package/template/workflows/specdev/common/rules/codebase-design.md +148 -0
- package/template/workflows/specdev/common/schemas/design-tree.schema.json +35 -0
- package/template/workflows/specdev/common/schemas/wayfinder-ticket.schema.json +19 -0
- package/template/workflows/specdev/common/skills/subagent-delivery/SKILL.md +61 -0
- package/template/workflows/specdev/common/skills/subagent-delivery/references/external-web-subagent.md +32 -0
- package/template/workflows/specdev/common/skills/subagent-delivery/references/github-checkpoints.md +24 -0
- package/template/workflows/specdev/common/skills/subagent-delivery/references/native-subagent.md +35 -0
- package/template/workflows/specdev/common/skills/subagent-delivery/references/source-package.md +17 -0
- package/template/workflows/specdev/common/tools/validate-specdev.mjs +226 -5
- package/template/skills/agents-md-builder/SKILL.md +0 -30
- package/template/skills/typescript-engineering-standards/README.md +0 -36
- package/template/skills/typescript-engineering-standards/SKILL.md +0 -158
- package/template/skills/typescript-engineering-standards/examples/comment-patterns.md +0 -47
- package/template/skills/typescript-engineering-standards/examples/naming-patterns.md +0 -42
- package/template/skills/typescript-engineering-standards/examples/project-layouts.md +0 -75
- package/template/skills/typescript-engineering-standards/examples/review-output-example.md +0 -25
- package/template/skills/typescript-engineering-standards/examples/type-modeling-patterns.md +0 -66
- package/template/skills/typescript-engineering-standards/manifest.txt +0 -33
- package/template/skills/typescript-engineering-standards/references/00-standard-levels-and-precedence.md +0 -51
- package/template/skills/typescript-engineering-standards/references/01-project-architecture-and-directory-layout.md +0 -105
- package/template/skills/typescript-engineering-standards/references/02-file-directory-and-symbol-naming.md +0 -117
- package/template/skills/typescript-engineering-standards/references/03-modules-imports-exports-and-dependencies.md +0 -111
- package/template/skills/typescript-engineering-standards/references/04-typescript-type-system.md +0 -150
- package/template/skills/typescript-engineering-standards/references/05-functions-async-errors-and-resources.md +0 -142
- package/template/skills/typescript-engineering-standards/references/06-comments-jsdoc-and-documentation.md +0 -104
- package/template/skills/typescript-engineering-standards/references/07-testing-strategy.md +0 -84
- package/template/skills/typescript-engineering-standards/references/08-react-and-frontend.md +0 -91
- package/template/skills/typescript-engineering-standards/references/09-node-cli-and-cross-platform.md +0 -92
- package/template/skills/typescript-engineering-standards/references/10-formatting-lint-and-complexity.md +0 -107
- package/template/skills/typescript-engineering-standards/references/11-configuration-dependencies-and-ci.md +0 -86
- package/template/skills/typescript-engineering-standards/references/12-security-performance-and-i18n.md +0 -65
- package/template/skills/typescript-engineering-standards/references/13-git-review-and-delivery.md +0 -79
- package/template/skills/typescript-engineering-standards/references/14-adoption-exceptions-and-migration.md +0 -84
- package/template/skills/typescript-engineering-standards/references/15-orca-derived-observations.md +0 -54
- package/template/skills/typescript-engineering-standards/references/README.md +0 -45
- package/template/skills/typescript-engineering-standards/templates/.editorconfig +0 -12
- package/template/skills/typescript-engineering-standards/templates/AGENTS.typescript.md +0 -21
- package/template/skills/typescript-engineering-standards/templates/code-review-checklist.md +0 -37
- package/template/skills/typescript-engineering-standards/templates/package-scripts.json +0 -11
- package/template/skills/typescript-engineering-standards/templates/prettier.json +0 -6
- package/template/skills/typescript-engineering-standards/templates/pull-request-template.md +0 -37
- package/template/skills/typescript-engineering-standards/templates/tsconfig.base.json +0 -17
- package/template/skills/typescript-engineering-standards/templates/tsconfig.project-references.json +0 -8
- package/template/workflows/specdev/I-implement/codebase-design-glossary.md +0 -12
- package/template/workflows/specdev/I-implement/deepening.md +0 -17
- /package/template/skills/{agents-md-builder/references → docs-sync/references/agents}/content-contract.md +0 -0
- /package/template/skills/{agents-md-builder/references → docs-sync/references/agents}/evidence-collection.md +0 -0
- /package/template/skills/{agents-md-builder/references → docs-sync/references/agents}/manifest-discovery.md +0 -0
- /package/template/skills/{agents-md-builder/references → docs-sync/references/agents}/role-classification.md +0 -0
- /package/template/skills/{agents-md-builder/references → docs-sync/references/agents}/templates/aggregator-AGENTS.md +0 -0
- /package/template/skills/{agents-md-builder/references → docs-sync/references/agents}/templates/capability-module-AGENTS.md +0 -0
- /package/template/skills/{agents-md-builder/references → docs-sync/references/agents}/templates/contract-module-AGENTS.md +0 -0
- /package/template/skills/{agents-md-builder/references → docs-sync/references/agents}/templates/repo-root-AGENTS.md +0 -0
- /package/template/skills/{agents-md-builder/references → docs-sync/references/agents}/templates/runnable-app-AGENTS.md +0 -0
- /package/template/skills/{agents-md-builder/references → docs-sync/references/agents}/templates/scripts-docs-AGENTS.md +0 -0
- /package/template/skills/{agents-md-builder/references → docs-sync/references/agents}/writing-style.md +0 -0
|
@@ -56,6 +56,22 @@ const VALID_PLAN_MODES = new Set([
|
|
|
56
56
|
"reference-conformance",
|
|
57
57
|
"release-coordination",
|
|
58
58
|
]);
|
|
59
|
+
const VALID_DESIGN_TREE_STATUS = new Set(["active", "consensus", "blocked"]);
|
|
60
|
+
const VALID_DESIGN_NODE_STATUS = new Set(["open", "answered", "deferred", "rejected"]);
|
|
61
|
+
const VALID_WAYFINDER_LABEL = new Set([
|
|
62
|
+
"wayfinder:research",
|
|
63
|
+
"wayfinder:prototype",
|
|
64
|
+
"wayfinder:grilling",
|
|
65
|
+
"wayfinder:task",
|
|
66
|
+
]);
|
|
67
|
+
const VALID_WAYFINDER_STATUS = new Set(["open", "closed"]);
|
|
68
|
+
const VALID_WAYFINDER_RESOLUTION = new Set([
|
|
69
|
+
null,
|
|
70
|
+
"answered",
|
|
71
|
+
"out-of-scope",
|
|
72
|
+
"superseded",
|
|
73
|
+
"cancelled",
|
|
74
|
+
]);
|
|
59
75
|
const REQUIRED_TICKET_KEYS = new Set([
|
|
60
76
|
"schema_version",
|
|
61
77
|
"artifact",
|
|
@@ -108,6 +124,7 @@ const STATE_ARTIFACT_BASENAMES = new Set([
|
|
|
108
124
|
"architecture-review.md",
|
|
109
125
|
"architecture-review.html",
|
|
110
126
|
"wayfinder-map.md",
|
|
127
|
+
"design-tree.json",
|
|
111
128
|
]);
|
|
112
129
|
const FORBIDDEN_OBSOLETE_BASENAMES = new Set([
|
|
113
130
|
"input-validation.md",
|
|
@@ -522,28 +539,38 @@ function capabilityChecks(root) {
|
|
|
522
539
|
"goal-plan",
|
|
523
540
|
[
|
|
524
541
|
join(root, "P-goal-plan", "P-goal-plan.md"),
|
|
525
|
-
[
|
|
542
|
+
[
|
|
543
|
+
"Outcome",
|
|
544
|
+
"Authority",
|
|
545
|
+
"DAG",
|
|
546
|
+
"Gate",
|
|
547
|
+
"Wave",
|
|
548
|
+
"Lead",
|
|
549
|
+
"Dispatch Packet",
|
|
550
|
+
"subagent-delivery",
|
|
551
|
+
"Definition of Done",
|
|
552
|
+
],
|
|
526
553
|
],
|
|
527
554
|
],
|
|
528
555
|
[
|
|
529
556
|
"implement",
|
|
530
557
|
[
|
|
531
558
|
join(root, "I-implement", "I-implement.md"),
|
|
532
|
-
["design-it-twice", "TDD", "双轴审查", "Evidence", "提交"],
|
|
559
|
+
["codebase-design", "design-it-twice", "TDD", "双轴审查", "Evidence", "delegated execution", "subagent-delivery", "提交"],
|
|
533
560
|
],
|
|
534
561
|
],
|
|
535
562
|
[
|
|
536
563
|
"wayfinder",
|
|
537
564
|
[
|
|
538
565
|
join(root, "W-wayfinder", "W-wayfinder.md"),
|
|
539
|
-
["共享地图", "claimed_investigations", "
|
|
566
|
+
["共享地图", "claimed_investigations", "wayfinder:prototype", "wayfinder:grilling", "solution comment", "每个会话"],
|
|
540
567
|
],
|
|
541
568
|
],
|
|
542
569
|
[
|
|
543
570
|
"architecture-review",
|
|
544
571
|
[
|
|
545
572
|
join(root, "R-review-architecture", "R-review-architecture.md"),
|
|
546
|
-
["
|
|
573
|
+
["shallow", "interface", "locality", "Tailwind CDN", "Mermaid CDN", "最佳推荐"],
|
|
547
574
|
],
|
|
548
575
|
],
|
|
549
576
|
[
|
|
@@ -557,7 +584,7 @@ function capabilityChecks(root) {
|
|
|
557
584
|
"grill",
|
|
558
585
|
[
|
|
559
586
|
join(root, "G-grill-with-docs", "G-grill-with-docs.md"),
|
|
560
|
-
["
|
|
587
|
+
["完整 frontier", "design-tree.json", "LOG.md", "CONTEXT.md", "ADR.md", "推荐答案"],
|
|
561
588
|
],
|
|
562
589
|
],
|
|
563
590
|
[
|
|
@@ -583,6 +610,28 @@ function capabilityChecks(root) {
|
|
|
583
610
|
}
|
|
584
611
|
if (!isFile(join(root, "R-review-architecture", "architecture-review-report-template.html"))) {
|
|
585
612
|
errors.push("architecture review lost its visual HTML report template");
|
|
613
|
+
} else {
|
|
614
|
+
const html = readText(join(root, "R-review-architecture", "architecture-review-report-template.html"));
|
|
615
|
+
for (const marker of ["cdn.tailwindcss.com", "mermaid", "Before", "After", "top-recommendation"]) {
|
|
616
|
+
if (!html.includes(marker)) errors.push(`architecture HTML template lost marker ${marker}`);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
for (const required of [
|
|
621
|
+
"common/rules/codebase-design.md",
|
|
622
|
+
"common/schemas/design-tree.schema.json",
|
|
623
|
+
"common/schemas/wayfinder-ticket.schema.json",
|
|
624
|
+
"G-grill-with-docs/design-tree-template.json",
|
|
625
|
+
"W-wayfinder/local-tracker-contract.md",
|
|
626
|
+
"W-wayfinder/solution-comment-template.md",
|
|
627
|
+
"R-review-architecture/architecture-report-contract.md",
|
|
628
|
+
]) {
|
|
629
|
+
if (!isFile(join(root, required))) errors.push(`missing architecture/wayfinding contract ${required}`);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
const mapTemplate = join(root, "W-wayfinder", "wayfinder-map-template.md");
|
|
633
|
+
if (isFile(mapTemplate) && /^## (?:开放 Tickets|调查清单)/m.test(readText(mapTemplate))) {
|
|
634
|
+
errors.push("Wayfinder map template must query open Tickets instead of caching them");
|
|
586
635
|
}
|
|
587
636
|
return errors;
|
|
588
637
|
}
|
|
@@ -777,6 +826,176 @@ function validateGoalPlan(path, errors) {
|
|
|
777
826
|
return { path, meta, body };
|
|
778
827
|
}
|
|
779
828
|
|
|
829
|
+
function validateDesignTree(path, change, errors) {
|
|
830
|
+
if (!isFile(path)) return null;
|
|
831
|
+
let data;
|
|
832
|
+
try {
|
|
833
|
+
data = JSON.parse(readText(path));
|
|
834
|
+
} catch (error) {
|
|
835
|
+
errors.push(`${basename(path)}: invalid JSON: ${error.message}`);
|
|
836
|
+
return null;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
if (data.schema_version !== 1 || data.artifact !== "design-tree") {
|
|
840
|
+
errors.push(`${basename(path)}: artifact/schema_version must be design-tree/1`);
|
|
841
|
+
}
|
|
842
|
+
if (data.change !== basename(change)) {
|
|
843
|
+
errors.push(`${basename(path)}: change must equal directory name ${basename(change)}`);
|
|
844
|
+
}
|
|
845
|
+
if (!VALID_DESIGN_TREE_STATUS.has(data.status)) {
|
|
846
|
+
errors.push(`${basename(path)}: invalid status ${data.status}`);
|
|
847
|
+
}
|
|
848
|
+
if (!Number.isInteger(data.round) || data.round < 0) {
|
|
849
|
+
errors.push(`${basename(path)}: round must be a non-negative integer`);
|
|
850
|
+
}
|
|
851
|
+
if (!Array.isArray(data.nodes)) {
|
|
852
|
+
errors.push(`${basename(path)}: nodes must be a list`);
|
|
853
|
+
return data;
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
const nodes = new Map();
|
|
857
|
+
const graph = new Map();
|
|
858
|
+
for (const node of data.nodes) {
|
|
859
|
+
const id = String(node?.id ?? "");
|
|
860
|
+
if (!/^D-\d{3,}$/.test(id)) errors.push(`${basename(path)}: invalid design node id ${id}`);
|
|
861
|
+
if (nodes.has(id)) errors.push(`${basename(path)}: duplicate design node id ${id}`);
|
|
862
|
+
nodes.set(id, node);
|
|
863
|
+
const dependencies = Array.isArray(node?.depends_on) ? node.depends_on.map(String) : [];
|
|
864
|
+
graph.set(id, dependencies);
|
|
865
|
+
if (!Array.isArray(node?.depends_on)) {
|
|
866
|
+
errors.push(`${basename(path)}: ${id} depends_on must be a list`);
|
|
867
|
+
}
|
|
868
|
+
for (const key of ["title", "question", "recommendation"]) {
|
|
869
|
+
if (!String(node?.[key] ?? "").trim()) errors.push(`${basename(path)}: ${id} ${key} is required`);
|
|
870
|
+
}
|
|
871
|
+
if (!VALID_DESIGN_NODE_STATUS.has(node?.status)) {
|
|
872
|
+
errors.push(`${basename(path)}: ${id} has invalid status ${node?.status}`);
|
|
873
|
+
}
|
|
874
|
+
if (node?.round !== null && (!Number.isInteger(node?.round) || node.round < 1)) {
|
|
875
|
+
errors.push(`${basename(path)}: ${id} round must be null or a positive integer`);
|
|
876
|
+
}
|
|
877
|
+
if (node?.status !== "open") {
|
|
878
|
+
if (!String(node?.answer ?? "").trim()) errors.push(`${basename(path)}: ${id} closed node needs an answer`);
|
|
879
|
+
if (!/^LOG-\d{3,}$/.test(String(node?.log_ref ?? ""))) {
|
|
880
|
+
errors.push(`${basename(path)}: ${id} closed node needs a LOG-### reference`);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
for (const [id, dependencies] of graph) {
|
|
886
|
+
for (const dependency of dependencies) {
|
|
887
|
+
if (!nodes.has(dependency)) errors.push(`${basename(path)}: ${id} depends on missing ${dependency}`);
|
|
888
|
+
if (dependency === id) errors.push(`${basename(path)}: ${id} cannot depend on itself`);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
const cycle = findCycle(graph);
|
|
892
|
+
if (cycle) errors.push(`Design tree dependency cycle: ${cycle.join(" -> ")}`);
|
|
893
|
+
if (
|
|
894
|
+
data.status === "consensus" &&
|
|
895
|
+
data.nodes.some((node) => new Set(["open", "deferred"]).has(node?.status))
|
|
896
|
+
) {
|
|
897
|
+
errors.push(`${basename(path)}: consensus design tree cannot contain open or deferred nodes`);
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
const logPath = join(change, "LOG.md");
|
|
901
|
+
const logText = isFile(logPath) ? readText(logPath) : "";
|
|
902
|
+
for (const node of data.nodes) {
|
|
903
|
+
if (node?.log_ref && !logText.includes(String(node.log_ref))) {
|
|
904
|
+
errors.push(`${basename(path)}: ${node.id} points to missing ${node.log_ref} in LOG`);
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
return data;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
function validateWayfinder(change, errors) {
|
|
911
|
+
const mapPath = join(change, "wayfinder-map.md");
|
|
912
|
+
const investigationDir = join(change, "investigation");
|
|
913
|
+
if (!isFile(mapPath) && !isDirectory(investigationDir)) return null;
|
|
914
|
+
if (!isFile(mapPath)) errors.push("Wayfinder investigations exist but the map is missing");
|
|
915
|
+
if (!isDirectory(investigationDir)) {
|
|
916
|
+
errors.push("Wayfinder map exists but the investigation directory is missing");
|
|
917
|
+
return null;
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
if (isFile(mapPath)) {
|
|
921
|
+
const { meta } = parseFrontmatter(mapPath);
|
|
922
|
+
if (meta.artifact !== "wayfinder-map") errors.push("wayfinder-map.md: artifact must be wayfinder-map");
|
|
923
|
+
if (meta.change !== basename(change)) {
|
|
924
|
+
errors.push(`wayfinder-map.md: change must equal directory name ${basename(change)}`);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
const ticketPaths = readdirSync(investigationDir, { withFileTypes: true })
|
|
929
|
+
.filter((entry) => entry.isFile() && entry.name.endsWith(".md"))
|
|
930
|
+
.map((entry) => join(investigationDir, entry.name))
|
|
931
|
+
.sort();
|
|
932
|
+
const tickets = new Map();
|
|
933
|
+
const graph = new Map();
|
|
934
|
+
for (const path of ticketPaths) {
|
|
935
|
+
const { meta } = parseFrontmatter(path);
|
|
936
|
+
const id = String(meta.id ?? "");
|
|
937
|
+
if (meta.artifact !== "wayfinder-ticket") {
|
|
938
|
+
errors.push(`${basename(path)}: artifact must be wayfinder-ticket`);
|
|
939
|
+
}
|
|
940
|
+
if (!/^INV-\d{2,}$/.test(id)) errors.push(`${basename(path)}: invalid Wayfinder Ticket id ${id}`);
|
|
941
|
+
if (tickets.has(id)) errors.push(`duplicate Wayfinder Ticket id ${id}`);
|
|
942
|
+
tickets.set(id, { path, meta });
|
|
943
|
+
if (!basename(path).startsWith(id)) errors.push(`${basename(path)}: filename must start with ${id}`);
|
|
944
|
+
if (!String(meta.name ?? "").trim()) errors.push(`${basename(path)}: name is required`);
|
|
945
|
+
const parentMap = typeof meta.parent_map === "string" ? stripPathTag(meta.parent_map) : null;
|
|
946
|
+
if (parentMap === null || !parentMap.endsWith("/wayfinder-map.md")) {
|
|
947
|
+
errors.push(`${basename(path)}: parent_map must be a rooted Wayfinder map Path`);
|
|
948
|
+
}
|
|
949
|
+
if (!VALID_WAYFINDER_LABEL.has(meta.label)) {
|
|
950
|
+
errors.push(`${basename(path)}: invalid Wayfinder label ${meta.label}`);
|
|
951
|
+
}
|
|
952
|
+
if (!VALID_WAYFINDER_STATUS.has(meta.status)) {
|
|
953
|
+
errors.push(`${basename(path)}: invalid Wayfinder status ${meta.status}`);
|
|
954
|
+
}
|
|
955
|
+
const dependencies = Array.isArray(meta.blocked_by) ? meta.blocked_by.map(String) : [];
|
|
956
|
+
if (!Array.isArray(meta.blocked_by)) errors.push(`${basename(path)}: blocked_by must be a list`);
|
|
957
|
+
graph.set(id, dependencies);
|
|
958
|
+
if (!VALID_WAYFINDER_RESOLUTION.has(meta.resolution)) {
|
|
959
|
+
errors.push(`${basename(path)}: invalid Wayfinder resolution ${meta.resolution}`);
|
|
960
|
+
}
|
|
961
|
+
if (meta.status === "open" && meta.resolution !== null) {
|
|
962
|
+
errors.push(`${basename(path)}: open Wayfinder Ticket must have resolution: null`);
|
|
963
|
+
}
|
|
964
|
+
if (meta.status === "closed" && meta.resolution === null) {
|
|
965
|
+
errors.push(`${basename(path)}: closed Wayfinder Ticket needs a resolution`);
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
for (const [id, dependencies] of graph) {
|
|
970
|
+
for (const dependency of dependencies) {
|
|
971
|
+
if (!tickets.has(dependency)) errors.push(`${id}: blocked_by references missing ${dependency}`);
|
|
972
|
+
if (dependency === id) errors.push(`${id}: Wayfinder Ticket cannot block itself`);
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
const cycle = findCycle(graph);
|
|
976
|
+
if (cycle) errors.push(`Wayfinder dependency cycle: ${cycle.join(" -> ")}`);
|
|
977
|
+
|
|
978
|
+
const commentsRoot = join(investigationDir, "comments");
|
|
979
|
+
for (const [id, ticket] of tickets) {
|
|
980
|
+
if (ticket.meta.status !== "closed") continue;
|
|
981
|
+
const commentDir = join(commentsRoot, id);
|
|
982
|
+
const comments = isDirectory(commentDir)
|
|
983
|
+
? readdirSync(commentDir).filter((name) => /^\d{2,}-solution\.md$/.test(name)).sort()
|
|
984
|
+
: [];
|
|
985
|
+
if (!comments.length) {
|
|
986
|
+
errors.push(`${id}: closed Wayfinder Ticket has no solution comment`);
|
|
987
|
+
continue;
|
|
988
|
+
}
|
|
989
|
+
for (const name of comments) {
|
|
990
|
+
const { meta } = parseFrontmatter(join(commentDir, name));
|
|
991
|
+
if (meta.artifact !== "wayfinder-solution-comment" || meta.ticket !== id) {
|
|
992
|
+
errors.push(`${toPosix(relative(change, join(commentDir, name)))}: invalid solution comment identity`);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
return tickets;
|
|
997
|
+
}
|
|
998
|
+
|
|
780
999
|
function validateTicket(path, errors) {
|
|
781
1000
|
const { meta, body } = parseFrontmatter(path);
|
|
782
1001
|
const missing = [...REQUIRED_TICKET_KEYS].filter((key) => !(key in meta));
|
|
@@ -930,6 +1149,8 @@ function validateChange(change) {
|
|
|
930
1149
|
const spec = validateSpec(join(change, "spec.md"), errors, warnings);
|
|
931
1150
|
const ticketsMap = validateMap(join(change, "tickets-map.md"), errors);
|
|
932
1151
|
const goalPlan = validateGoalPlan(join(change, "goal-plan.md"), errors);
|
|
1152
|
+
validateDesignTree(join(change, "design-tree.json"), change, errors);
|
|
1153
|
+
validateWayfinder(change, errors);
|
|
933
1154
|
for (const artifact of [spec, ticketsMap, goalPlan]) {
|
|
934
1155
|
if (artifact && artifact.meta.change !== basename(change)) {
|
|
935
1156
|
errors.push(`${basename(artifact.path)}: change must equal directory name ${basename(change)}`);
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: agents-md-builder
|
|
3
|
-
type: skill
|
|
4
|
-
name: AGENTS.md Builder
|
|
5
|
-
description: 扫描 manifest 目录并生成有证据、极简且形成父子导航树的 AGENTS.md 与 CLAUDE.md。
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# AGENTS.md Builder
|
|
9
|
-
|
|
10
|
-
每份 AGENTS.md 是模块导读。逐行执行删除测试:删除后不会使代理犯错的内容不进入产物。
|
|
11
|
-
|
|
12
|
-
## 输入
|
|
13
|
-
|
|
14
|
-
- 项目根(默认 runtime context 的 project root)与可选目标子树。
|
|
15
|
-
- 可选 manifest 类型过滤和输出语言(默认中文)。
|
|
16
|
-
|
|
17
|
-
## 流程
|
|
18
|
-
|
|
19
|
-
1. 读取 `references/manifest-discovery.md`,发现 manifest 目录、忽略目录和父子树;同时列出无 manifest 却存在代理手册的目录。完成标准:扫描范围内每个 manifest 恰好出现一次,所有孤立手册已列为候选而未直接删除。
|
|
20
|
-
2. 读取 `references/role-classification.md`,按优先级为每个目录判定唯一角色。完成标准:所有目录都有角色及支持证据,没有多重分类。
|
|
21
|
-
3. 读取 `references/evidence-collection.md`,收集 manifest、入口、依赖、消费方和测试。完成标准:每个将写入的结论都能指向真实文件。
|
|
22
|
-
4. 读取 `references/content-contract.md`、`references/writing-style.md` 和对应 `references/templates/*`,自底向上生成或更新 AGENTS.md。完成标准:父子 routing 完整、内容不跨模块重复且逐行通过删除测试。
|
|
23
|
-
5. 读取 `references/claude-redirect.md` 生成同层 CLAUDE.md;展示创建、更新和删除候选,确认后再写入。完成标准:每个合法 AGENTS.md 有唯一重定向,非法候选的处置有记录。
|
|
24
|
-
|
|
25
|
-
## 输出
|
|
26
|
-
|
|
27
|
-
- 生成/更新的 AGENTS.md 与 CLAUDE.md 清单。
|
|
28
|
-
- 按角色统计、证据缺口和经确认清理的孤立文件清单。
|
|
29
|
-
|
|
30
|
-
本 skill 不自行选择 Speculo 报告路径;需要持久化时由调用方提供。
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# TypeScript Engineering Standards Skill
|
|
2
|
-
|
|
3
|
-
这是一个采用渐进式披露结构的通用 TypeScript 工程规范 Skill。
|
|
4
|
-
|
|
5
|
-
## 使用方式
|
|
6
|
-
|
|
7
|
-
将整个 `typescript-engineering-standards/` 目录放入支持 Skill 的目录中,并以 `SKILL.md` 作为入口。不同平台的 Skill 安装位置可能不同;保持目录内部相对路径不变即可。
|
|
8
|
-
|
|
9
|
-
## 目录说明
|
|
10
|
-
|
|
11
|
-
```text
|
|
12
|
-
typescript-engineering-standards/
|
|
13
|
-
├── SKILL.md # 主入口:触发条件、工作流、参考路由
|
|
14
|
-
├── references/ # 详细规范,按任务最小化读取
|
|
15
|
-
├── templates/ # AGENTS、tsconfig、格式化、PR 与评审模板
|
|
16
|
-
├── examples/ # 目录、命名、类型、注释和审查示例
|
|
17
|
-
└── manifest.txt # 包内文件清单
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## 设计原则
|
|
21
|
-
|
|
22
|
-
- `SKILL.md` 保持相对精简,不承载所有细节。
|
|
23
|
-
- 详细规则按主题拆分到 `references/`。
|
|
24
|
-
- 执行具体任务时只读取必要参考。
|
|
25
|
-
- 模板是起点,不直接覆盖现有仓库配置。
|
|
26
|
-
- 用户要求、平台约束和仓库事实优先于通用默认规则。
|
|
27
|
-
|
|
28
|
-
## 推荐入口
|
|
29
|
-
|
|
30
|
-
- 创建或审查项目目录:`references/01-project-architecture-and-directory-layout.md`
|
|
31
|
-
- 文件和标识符命名:`references/02-file-directory-and-symbol-naming.md`
|
|
32
|
-
- TypeScript 类型安全:`references/04-typescript-type-system.md`
|
|
33
|
-
- 注释和 JSDoc:`references/06-comments-jsdoc-and-documentation.md`
|
|
34
|
-
- 测试:`references/07-testing-strategy.md`
|
|
35
|
-
- 格式化、Lint、复杂度:`references/10-formatting-lint-and-complexity.md`
|
|
36
|
-
- CI 和质量门禁:`references/11-configuration-dependencies-and-ci.md`
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: typescript-engineering-standards
|
|
3
|
-
description: 为 TypeScript、JavaScript、React、Node.js、Electron、CLI、npm 库与 Monorepo 项目提供可渐进加载的工程规范。用于新建项目、生成代码、目录设计、命名、类型建模、代码审查、重构、测试、Lint、CI、安全与质量门禁;详细规则按任务从 references/ 中最小化读取。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# TypeScript Engineering Standards Skill
|
|
7
|
-
|
|
8
|
-
本 Skill 将 TypeScript 工程规范拆成一个轻量主入口和多个主题参考文档。执行任务时采用**渐进式披露**:先判断任务类型,再只读取必要参考,避免把全部规范一次性加入上下文。
|
|
9
|
-
|
|
10
|
-
## 适用任务
|
|
11
|
-
|
|
12
|
-
在以下任务中使用本 Skill:
|
|
13
|
-
|
|
14
|
-
- 设计或调整 TypeScript 项目目录。
|
|
15
|
-
- 创建、重命名、移动 `.ts`、`.tsx`、测试或声明文件。
|
|
16
|
-
- 编写、补全、重构或审查 TypeScript/React/Node.js 代码。
|
|
17
|
-
- 制定团队编码规范、`AGENTS.md`、`CONTRIBUTING.md` 或 PR 检查清单。
|
|
18
|
-
- 配置 TypeScript、格式化、Lint、测试、构建与 CI。
|
|
19
|
-
- 处理类型安全、异步、错误、资源清理、安全、性能或跨平台问题。
|
|
20
|
-
- 对现有仓库做工程质量审计。
|
|
21
|
-
|
|
22
|
-
不在以下场景机械套用:
|
|
23
|
-
|
|
24
|
-
- 用户明确指定了不同规范。
|
|
25
|
-
- 框架、生成器或公开 API 有不可违背的约定。
|
|
26
|
-
- 任务仅是解释一段代码且不涉及代码修改或规范判断。
|
|
27
|
-
|
|
28
|
-
## 规则优先级
|
|
29
|
-
|
|
30
|
-
发生冲突时依次遵循:
|
|
31
|
-
|
|
32
|
-
1. 用户的明确要求。
|
|
33
|
-
2. 当前仓库已生效的配置、公共 API 与框架约定。
|
|
34
|
-
3. 当前模块已经形成且一致的局部惯例。
|
|
35
|
-
4. 本 Skill 的通用默认规则。
|
|
36
|
-
|
|
37
|
-
不要为了符合本 Skill 而进行与任务无关的大规模重命名、格式化或架构迁移。发现历史问题时,区分“本次必须修复”和“建议后续治理”。
|
|
38
|
-
|
|
39
|
-
## 核心执行流程
|
|
40
|
-
|
|
41
|
-
### 1. 识别任务和边界
|
|
42
|
-
|
|
43
|
-
先判断:
|
|
44
|
-
|
|
45
|
-
- 项目类型:Web、React、Node.js、Electron、CLI、库或 Monorepo。
|
|
46
|
-
- 任务类型:新建、增量开发、重构、审查、修复、规范制定或配置。
|
|
47
|
-
- 运行边界:浏览器、服务端、主进程、预加载、Worker、测试环境。
|
|
48
|
-
- 变更范围:单文件、单领域、跨模块或全仓库。
|
|
49
|
-
|
|
50
|
-
### 2. 检查仓库事实
|
|
51
|
-
|
|
52
|
-
修改现有项目时,优先检查:
|
|
53
|
-
|
|
54
|
-
- `package.json` 与锁文件。
|
|
55
|
-
- `tsconfig*.json`。
|
|
56
|
-
- ESLint、Oxlint、Prettier、Oxfmt、Biome 等配置。
|
|
57
|
-
- 测试配置与现有测试命名。
|
|
58
|
-
- `src/` 目录结构、路径别名和导出方式。
|
|
59
|
-
- `AGENTS.md`、`CONTRIBUTING.md`、README 与 CI 工作流。
|
|
60
|
-
|
|
61
|
-
不要假设项目使用 React、ESLint、Prettier、Vitest、Zod 或某种模块系统。
|
|
62
|
-
|
|
63
|
-
### 3. 最小化读取参考文档
|
|
64
|
-
|
|
65
|
-
仅加载与任务直接相关的参考文档。只有进行全仓库规范设计或综合审计时,才读取多个主题。
|
|
66
|
-
|
|
67
|
-
| 任务 | 首选参考 |
|
|
68
|
-
|---|---|
|
|
69
|
-
| 判断规则强度、处理冲突 | `references/00-standard-levels-and-precedence.md` |
|
|
70
|
-
| 设计目录、拆模块、平铺策略 | `references/01-project-architecture-and-directory-layout.md` |
|
|
71
|
-
| 文件、目录、变量、类型命名 | `references/02-file-directory-and-symbol-naming.md` |
|
|
72
|
-
| 导入、导出、Barrel、依赖方向 | `references/03-modules-imports-exports-and-dependencies.md` |
|
|
73
|
-
| 类型、`unknown`、联合、声明文件 | `references/04-typescript-type-system.md` |
|
|
74
|
-
| 函数、异步、错误、资源生命周期 | `references/05-functions-async-errors-and-resources.md` |
|
|
75
|
-
| 注释、JSDoc、TODO、文档 | `references/06-comments-jsdoc-and-documentation.md` |
|
|
76
|
-
| 单元、集成、契约、E2E 测试 | `references/07-testing-strategy.md` |
|
|
77
|
-
| React、Hook、状态、可访问性 | `references/08-react-and-frontend.md` |
|
|
78
|
-
| Node.js、CLI、路径、环境变量 | `references/09-node-cli-and-cross-platform.md` |
|
|
79
|
-
| 格式、Lint、文件大小、复杂度 | `references/10-formatting-lint-and-complexity.md` |
|
|
80
|
-
| 配置、依赖、脚本、CI | `references/11-configuration-dependencies-and-ci.md` |
|
|
81
|
-
| 安全、性能、国际化 | `references/12-security-performance-and-i18n.md` |
|
|
82
|
-
| Git、PR、评审和交付 | `references/13-git-review-and-delivery.md` |
|
|
83
|
-
| 老项目迁移、例外和渐进治理 | `references/14-adoption-exceptions-and-migration.md` |
|
|
84
|
-
| 了解 Orca 中提炼出的工程习惯 | `references/15-orca-derived-observations.md` |
|
|
85
|
-
|
|
86
|
-
完整索引见 `references/README.md`。
|
|
87
|
-
|
|
88
|
-
### 4. 应用核心默认规则
|
|
89
|
-
|
|
90
|
-
除非仓库事实或用户要求另有规定,默认遵守:
|
|
91
|
-
|
|
92
|
-
- 先按运行环境和业务领域划分边界,领域内部局部平铺。
|
|
93
|
-
- 文件名表达“领域 + 职责”,避免 `utils`、`helpers`、`common`、`misc` 等模糊名称。
|
|
94
|
-
- 一个文件只有一个主要职责;不要为单个文件机械创建目录。
|
|
95
|
-
- 默认使用命名导出,控制公共 API,禁止无意义全局 Barrel。
|
|
96
|
-
- TypeScript 开启严格模式;外部输入先作为 `unknown` 并在边界验证。
|
|
97
|
-
- 优先使用可辨识联合表达状态,使无效状态难以构造。
|
|
98
|
-
- 所有 Promise、监听器、Timer、连接和进程都有明确处理与清理路径。
|
|
99
|
-
- 注释解释原因、约束与权衡,不逐行翻译代码。
|
|
100
|
-
- 单元测试靠近源码;跨模块集成与 E2E 测试放在独立测试目录。
|
|
101
|
-
- 通过格式化、Lint、类型检查、测试和构建形成自动化门禁。
|
|
102
|
-
|
|
103
|
-
### 5. 生成或修改代码
|
|
104
|
-
|
|
105
|
-
生成代码时:
|
|
106
|
-
|
|
107
|
-
- 遵循仓库现有模块系统和格式风格。
|
|
108
|
-
- 新公开函数写明确返回类型。
|
|
109
|
-
- 不引入未经请求的新框架或依赖。
|
|
110
|
-
- 不用 `any`、双重断言、规则禁用或删除测试掩盖问题。
|
|
111
|
-
- 需要外部验证时,在边界层完成,不把不可信类型传播到内部。
|
|
112
|
-
- 修复缺陷时优先补回归测试。
|
|
113
|
-
- 只修改任务相关文件,避免格式噪声。
|
|
114
|
-
|
|
115
|
-
### 6. 审查和输出
|
|
116
|
-
|
|
117
|
-
代码审查时按以下优先级报告:
|
|
118
|
-
|
|
119
|
-
1. 正确性、安全和数据损坏风险。
|
|
120
|
-
2. 类型系统未覆盖的运行时风险。
|
|
121
|
-
3. 资源泄漏、竞态、取消与错误处理。
|
|
122
|
-
4. 架构边界、循环依赖和公共 API。
|
|
123
|
-
5. 测试缺口。
|
|
124
|
-
6. 命名、文件大小和可维护性。
|
|
125
|
-
7. 纯风格建议。
|
|
126
|
-
|
|
127
|
-
每条问题尽量包含:位置、风险、触发条件、修复方向。不要把个人偏好描述成缺陷。
|
|
128
|
-
|
|
129
|
-
## 常用模板
|
|
130
|
-
|
|
131
|
-
- 精简团队规则:`templates/AGENTS.typescript.md`
|
|
132
|
-
- 严格 TypeScript 基线:`templates/tsconfig.base.json`
|
|
133
|
-
- 多环境项目引用:`templates/tsconfig.project-references.json`
|
|
134
|
-
- 格式化基线:`templates/prettier.json`
|
|
135
|
-
- 编辑器基线:`templates/.editorconfig`
|
|
136
|
-
- npm 脚本示例:`templates/package-scripts.json`
|
|
137
|
-
- PR 模板:`templates/pull-request-template.md`
|
|
138
|
-
- 代码评审清单:`templates/code-review-checklist.md`
|
|
139
|
-
|
|
140
|
-
模板是起点,不得在未检查项目工具链时直接覆盖现有配置。
|
|
141
|
-
|
|
142
|
-
## 示例
|
|
143
|
-
|
|
144
|
-
- 项目目录示例:`examples/project-layouts.md`
|
|
145
|
-
- 命名模式示例:`examples/naming-patterns.md`
|
|
146
|
-
- 类型建模示例:`examples/type-modeling-patterns.md`
|
|
147
|
-
- 注释示例:`examples/comment-patterns.md`
|
|
148
|
-
- 审查输出示例:`examples/review-output-example.md`
|
|
149
|
-
|
|
150
|
-
## 交付要求
|
|
151
|
-
|
|
152
|
-
完成任务前确认:
|
|
153
|
-
|
|
154
|
-
- 变更符合当前仓库事实,而非仅符合抽象规范。
|
|
155
|
-
- 必要测试和质量检查已执行,或明确说明未能执行的项目。
|
|
156
|
-
- 没有增加无意义目录、模糊文件名或隐藏依赖。
|
|
157
|
-
- 没有通过削弱类型、关闭规则或跳过测试来获得表面通过。
|
|
158
|
-
- 输出聚焦本次任务;更广泛的治理建议单独列出,不混入必要修复。
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# 注释模式示例
|
|
2
|
-
|
|
3
|
-
## 兼容性
|
|
4
|
-
|
|
5
|
-
```ts
|
|
6
|
-
// Why: Windows reports the executable path with inconsistent drive-letter casing.
|
|
7
|
-
const normalizedPath = normalizeWindowsDriveLetter(executablePath)
|
|
8
|
-
```
|
|
9
|
-
|
|
10
|
-
## 第三方缺陷
|
|
11
|
-
|
|
12
|
-
```ts
|
|
13
|
-
// Why: SDK 4.2 can invoke this callback twice after cancellation.
|
|
14
|
-
if (requestState.isSettled) {
|
|
15
|
-
return
|
|
16
|
-
}
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## 安全顺序
|
|
20
|
-
|
|
21
|
-
```ts
|
|
22
|
-
// Validate before resolving the path so traversal segments cannot escape the root.
|
|
23
|
-
const safeRelativePath = parseRelativePath(input)
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## 性能
|
|
27
|
-
|
|
28
|
-
```ts
|
|
29
|
-
// Keep the compiled expression outside the hot loop; this runs for every log line.
|
|
30
|
-
const ansiPattern = createAnsiPattern()
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## 不推荐
|
|
34
|
-
|
|
35
|
-
```ts
|
|
36
|
-
// Loop through items.
|
|
37
|
-
for (const item of items) {
|
|
38
|
-
// Add the item.
|
|
39
|
-
results.push(item)
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## TODO
|
|
44
|
-
|
|
45
|
-
```ts
|
|
46
|
-
// TODO(PROJ-1423): Remove the v2 fallback after desktop 3.8 reaches 95% adoption.
|
|
47
|
-
```
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# 命名示例
|
|
2
|
-
|
|
3
|
-
## 从模糊名称改为具体名称
|
|
4
|
-
|
|
5
|
-
| 模糊 | 推荐 |
|
|
6
|
-
|---|---|
|
|
7
|
-
| `utils.ts` | `shell-command-quote.ts` |
|
|
8
|
-
| `helpers.ts` | `workspace-path-normalize.ts` |
|
|
9
|
-
| `manager.ts` | `terminal-process-registry.ts` |
|
|
10
|
-
| `handler.ts` | `payment-webhook-handler.ts` |
|
|
11
|
-
| `service.ts` | `user-session-service.ts` |
|
|
12
|
-
| `data.ts` | `workspace-summary.ts` |
|
|
13
|
-
| `types.ts` | `payment-contract.ts` |
|
|
14
|
-
| `constants.ts` | `terminal-limits.ts` |
|
|
15
|
-
|
|
16
|
-
## 函数
|
|
17
|
-
|
|
18
|
-
| 含义弱 | 推荐 |
|
|
19
|
-
|---|---|
|
|
20
|
-
| `handle()` | `handleWorkspaceClosed()` |
|
|
21
|
-
| `process()` | `parseTerminalOutput()` |
|
|
22
|
-
| `check()` | `validateWorkspacePath()` |
|
|
23
|
-
| `getData()` | `loadUserProfile()` |
|
|
24
|
-
| `doRetry()` | `retryPaymentCapture()` |
|
|
25
|
-
|
|
26
|
-
## 布尔值
|
|
27
|
-
|
|
28
|
-
| 含义弱 | 推荐 |
|
|
29
|
-
|---|---|
|
|
30
|
-
| `flag` | `shouldPersist` |
|
|
31
|
-
| `enabled` | `isTelemetryEnabled` |
|
|
32
|
-
| `valid` | `isWorkspacePathValid` |
|
|
33
|
-
| `notReady` | `isInitializing` 或 `isReady` |
|
|
34
|
-
|
|
35
|
-
## 单位
|
|
36
|
-
|
|
37
|
-
| 含义弱 | 推荐 |
|
|
38
|
-
|---|---|
|
|
39
|
-
| `timeout` | `timeoutMs` |
|
|
40
|
-
| `size` | `payloadSizeBytes` |
|
|
41
|
-
| `delay` | `retryDelayMs` |
|
|
42
|
-
| `limit` | `pageSizeLimit` |
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
# 项目目录示例
|
|
2
|
-
|
|
3
|
-
## 小型 Node 服务
|
|
4
|
-
|
|
5
|
-
```text
|
|
6
|
-
src/
|
|
7
|
-
├── app/
|
|
8
|
-
│ ├── create-server.ts
|
|
9
|
-
│ └── load-environment.ts
|
|
10
|
-
├── features/
|
|
11
|
-
│ └── user-auth/
|
|
12
|
-
│ ├── authenticate-user.ts
|
|
13
|
-
│ ├── authenticate-user.test.ts
|
|
14
|
-
│ └── user-token.ts
|
|
15
|
-
├── infrastructure/
|
|
16
|
-
│ ├── database/
|
|
17
|
-
│ └── http/
|
|
18
|
-
└── shared/
|
|
19
|
-
└── result.ts
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
## React 应用
|
|
23
|
-
|
|
24
|
-
```text
|
|
25
|
-
src/
|
|
26
|
-
├── app/
|
|
27
|
-
│ ├── App.tsx
|
|
28
|
-
│ └── routes.tsx
|
|
29
|
-
├── features/
|
|
30
|
-
│ ├── workspace-search/
|
|
31
|
-
│ │ ├── WorkspaceSearchPanel.tsx
|
|
32
|
-
│ │ ├── workspace-search-query.ts
|
|
33
|
-
│ │ └── use-workspace-search.ts
|
|
34
|
-
│ └── user-settings/
|
|
35
|
-
├── shared/
|
|
36
|
-
│ ├── components/
|
|
37
|
-
│ └── hooks/
|
|
38
|
-
└── infrastructure/
|
|
39
|
-
└── api/
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
`shared/components` 只放真正无业务归属且有多个真实调用方的组件。
|
|
43
|
-
|
|
44
|
-
## Electron
|
|
45
|
-
|
|
46
|
-
```text
|
|
47
|
-
src/
|
|
48
|
-
├── main/
|
|
49
|
-
│ ├── app-lifecycle.ts
|
|
50
|
-
│ └── windows/
|
|
51
|
-
├── preload/
|
|
52
|
-
│ └── workspace-api.ts
|
|
53
|
-
├── renderer/
|
|
54
|
-
│ ├── app/
|
|
55
|
-
│ └── features/
|
|
56
|
-
├── shared/
|
|
57
|
-
│ └── workspace-contract.ts
|
|
58
|
-
└── types/
|
|
59
|
-
└── electron-api.d.ts
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## Monorepo
|
|
63
|
-
|
|
64
|
-
```text
|
|
65
|
-
apps/
|
|
66
|
-
├── web/
|
|
67
|
-
└── api/
|
|
68
|
-
packages/
|
|
69
|
-
├── domain/
|
|
70
|
-
├── contracts/
|
|
71
|
-
├── ui/
|
|
72
|
-
└── test-support/
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
包边界应与独立发布、运行环境或稳定依赖方向对应,不要仅为缩短相对路径拆包。
|