forgecraft-mcp 1.2.0 → 1.4.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 +525 -525
- package/dist/artifacts/commit-hooks.d.ts +1 -1
- package/dist/artifacts/commit-hooks.d.ts.map +1 -1
- package/dist/artifacts/commit-hooks.js +2 -0
- package/dist/artifacts/commit-hooks.js.map +1 -1
- package/dist/cli/commands.d.ts +35 -1
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +109 -2
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +51 -44
- package/dist/cli/help.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +10 -1
- package/dist/cli.js.map +1 -1
- package/dist/registry/renderer-skeletons.js +92 -92
- package/dist/shared/gs-score-logger.js +6 -6
- package/dist/shared/result-utils.d.ts +27 -0
- package/dist/shared/result-utils.d.ts.map +1 -0
- package/dist/shared/result-utils.js +41 -0
- package/dist/shared/result-utils.js.map +1 -0
- package/dist/tools/add-module.js +123 -123
- package/dist/tools/advice-registry.js +18 -18
- package/dist/tools/check-cascade-report.js +64 -64
- package/dist/tools/close-cycle-helpers.d.ts +21 -2
- package/dist/tools/close-cycle-helpers.d.ts.map +1 -1
- package/dist/tools/close-cycle-helpers.js +66 -10
- package/dist/tools/close-cycle-helpers.js.map +1 -1
- package/dist/tools/close-cycle.d.ts +2 -2
- package/dist/tools/close-cycle.d.ts.map +1 -1
- package/dist/tools/close-cycle.js +1 -1
- package/dist/tools/close-cycle.js.map +1 -1
- package/dist/tools/configure-mcp.d.ts +3 -0
- package/dist/tools/configure-mcp.d.ts.map +1 -1
- package/dist/tools/configure-mcp.js +10 -0
- package/dist/tools/configure-mcp.js.map +1 -1
- package/dist/tools/consolidate-status.d.ts +81 -0
- package/dist/tools/consolidate-status.d.ts.map +1 -0
- package/dist/tools/consolidate-status.js +251 -0
- package/dist/tools/consolidate-status.js.map +1 -0
- package/dist/tools/forgecraft-dispatch.d.ts.map +1 -1
- package/dist/tools/forgecraft-dispatch.js +13 -0
- package/dist/tools/forgecraft-dispatch.js.map +1 -1
- package/dist/tools/forgecraft-router.d.ts +8 -0
- package/dist/tools/forgecraft-router.d.ts.map +1 -1
- package/dist/tools/forgecraft-router.js +21 -1
- package/dist/tools/forgecraft-router.js.map +1 -1
- package/dist/tools/forgecraft-schema-params.d.ts +13 -4
- package/dist/tools/forgecraft-schema-params.d.ts.map +1 -1
- package/dist/tools/forgecraft-schema-params.js +21 -0
- package/dist/tools/forgecraft-schema-params.js.map +1 -1
- package/dist/tools/forgecraft-schema.d.ts +14 -5
- package/dist/tools/forgecraft-schema.d.ts.map +1 -1
- package/dist/tools/forgecraft-schema.js +3 -0
- package/dist/tools/forgecraft-schema.js.map +1 -1
- package/dist/tools/gate-violations.d.ts +59 -0
- package/dist/tools/gate-violations.d.ts.map +1 -0
- package/dist/tools/gate-violations.js +152 -0
- package/dist/tools/gate-violations.js.map +1 -0
- package/dist/tools/generate-session-prompt.d.ts +3 -3
- package/dist/tools/generate-session-prompt.d.ts.map +1 -1
- package/dist/tools/generate-session-prompt.js +57 -15
- package/dist/tools/generate-session-prompt.js.map +1 -1
- package/dist/tools/refresh-output.js +14 -14
- package/dist/tools/roadmap-builder.d.ts.map +1 -1
- package/dist/tools/roadmap-builder.js +19 -9
- package/dist/tools/roadmap-builder.js.map +1 -1
- package/dist/tools/scaffold-spec-stubs.js +115 -115
- package/dist/tools/scaffold-templates.js +62 -62
- package/dist/tools/session-prompt-builders.d.ts.map +1 -1
- package/dist/tools/session-prompt-builders.js +34 -10
- package/dist/tools/session-prompt-builders.js.map +1 -1
- package/dist/tools/setup-artifact-writers.d.ts +30 -0
- package/dist/tools/setup-artifact-writers.d.ts.map +1 -1
- package/dist/tools/setup-artifact-writers.js +120 -8
- package/dist/tools/setup-artifact-writers.js.map +1 -1
- package/dist/tools/setup-phase1.d.ts +3 -0
- package/dist/tools/setup-phase1.d.ts.map +1 -1
- package/dist/tools/setup-phase1.js +79 -35
- package/dist/tools/setup-phase1.js.map +1 -1
- package/dist/tools/setup-phase2.d.ts +2 -0
- package/dist/tools/setup-phase2.d.ts.map +1 -1
- package/dist/tools/setup-phase2.js +10 -1
- package/dist/tools/setup-phase2.js.map +1 -1
- package/dist/tools/setup-project.d.ts +18 -0
- package/dist/tools/setup-project.d.ts.map +1 -1
- package/dist/tools/setup-project.js +77 -1
- package/dist/tools/setup-project.js.map +1 -1
- package/dist/tools/spec-parser-tags.d.ts +9 -0
- package/dist/tools/spec-parser-tags.d.ts.map +1 -1
- package/dist/tools/spec-parser-tags.js +92 -0
- package/dist/tools/spec-parser-tags.js.map +1 -1
- package/package.json +89 -86
- package/templates/analytics/instructions.yaml +37 -37
- package/templates/analytics/mcp-servers.yaml +11 -11
- package/templates/analytics/structure.yaml +25 -25
- package/templates/api/instructions.yaml +231 -231
- package/templates/api/mcp-servers.yaml +22 -13
- package/templates/api/nfr.yaml +23 -23
- package/templates/api/review.yaml +103 -103
- package/templates/api/structure.yaml +34 -34
- package/templates/api/verification.yaml +132 -132
- package/templates/cli/instructions.yaml +31 -31
- package/templates/cli/mcp-servers.yaml +11 -11
- package/templates/cli/review.yaml +53 -53
- package/templates/cli/structure.yaml +16 -16
- package/templates/data-lineage/instructions.yaml +28 -28
- package/templates/data-lineage/mcp-servers.yaml +22 -22
- package/templates/data-pipeline/instructions.yaml +84 -84
- package/templates/data-pipeline/mcp-servers.yaml +13 -13
- package/templates/data-pipeline/nfr.yaml +39 -39
- package/templates/data-pipeline/structure.yaml +23 -23
- package/templates/fintech/hooks.yaml +55 -55
- package/templates/fintech/instructions.yaml +112 -112
- package/templates/fintech/mcp-servers.yaml +13 -13
- package/templates/fintech/nfr.yaml +46 -46
- package/templates/fintech/playbook.yaml +210 -210
- package/templates/fintech/verification.yaml +239 -239
- package/templates/game/instructions.yaml +289 -289
- package/templates/game/mcp-servers.yaml +38 -38
- package/templates/game/nfr.yaml +64 -64
- package/templates/game/playbook.yaml +214 -214
- package/templates/game/review.yaml +97 -97
- package/templates/game/structure.yaml +67 -67
- package/templates/game/verification.yaml +174 -174
- package/templates/healthcare/instructions.yaml +42 -42
- package/templates/healthcare/mcp-servers.yaml +13 -13
- package/templates/healthcare/nfr.yaml +47 -47
- package/templates/hipaa/instructions.yaml +41 -41
- package/templates/hipaa/mcp-servers.yaml +13 -13
- package/templates/infra/instructions.yaml +104 -104
- package/templates/infra/mcp-servers.yaml +20 -20
- package/templates/infra/nfr.yaml +46 -46
- package/templates/infra/review.yaml +65 -65
- package/templates/infra/structure.yaml +25 -25
- package/templates/library/instructions.yaml +36 -36
- package/templates/library/mcp-servers.yaml +20 -20
- package/templates/library/review.yaml +56 -56
- package/templates/library/structure.yaml +19 -19
- package/templates/medallion-architecture/instructions.yaml +41 -41
- package/templates/medallion-architecture/mcp-servers.yaml +22 -22
- package/templates/ml/instructions.yaml +85 -85
- package/templates/ml/mcp-servers.yaml +11 -11
- package/templates/ml/nfr.yaml +39 -39
- package/templates/ml/structure.yaml +25 -25
- package/templates/ml/verification.yaml +156 -156
- package/templates/mobile/instructions.yaml +44 -44
- package/templates/mobile/mcp-servers.yaml +11 -11
- package/templates/mobile/nfr.yaml +49 -49
- package/templates/mobile/structure.yaml +27 -27
- package/templates/mobile/verification.yaml +121 -121
- package/templates/observability-xray/instructions.yaml +40 -40
- package/templates/observability-xray/mcp-servers.yaml +15 -15
- package/templates/realtime/instructions.yaml +42 -42
- package/templates/realtime/mcp-servers.yaml +13 -13
- package/templates/soc2/instructions.yaml +41 -41
- package/templates/soc2/mcp-servers.yaml +24 -24
- package/templates/social/instructions.yaml +43 -43
- package/templates/social/mcp-servers.yaml +24 -24
- package/templates/state-machine/instructions.yaml +42 -42
- package/templates/state-machine/mcp-servers.yaml +11 -11
- package/templates/tools-registry.yaml +164 -164
- package/templates/universal/hooks.yaml +723 -531
- package/templates/universal/instructions.yaml +1692 -1692
- package/templates/universal/mcp-servers.yaml +50 -50
- package/templates/universal/nfr.yaml +197 -197
- package/templates/universal/reference.yaml +326 -326
- package/templates/universal/review.yaml +204 -204
- package/templates/universal/skills.yaml +262 -262
- package/templates/universal/structure.yaml +67 -67
- package/templates/universal/verification.yaml +416 -416
- package/templates/web-react/hooks.yaml +44 -44
- package/templates/web-react/instructions.yaml +207 -207
- package/templates/web-react/mcp-servers.yaml +20 -20
- package/templates/web-react/nfr.yaml +27 -27
- package/templates/web-react/review.yaml +94 -94
- package/templates/web-react/structure.yaml +46 -46
- package/templates/web-react/verification.yaml +126 -126
- package/templates/web-static/instructions.yaml +115 -115
- package/templates/web-static/mcp-servers.yaml +20 -20
- package/templates/web3/instructions.yaml +44 -44
- package/templates/web3/mcp-servers.yaml +11 -11
- package/templates/web3/verification.yaml +159 -159
- package/templates/zero-trust/instructions.yaml +41 -41
- package/templates/zero-trust/mcp-servers.yaml +15 -15
|
@@ -11,42 +11,42 @@
|
|
|
11
11
|
* @returns Status.md content ready to write
|
|
12
12
|
*/
|
|
13
13
|
export function renderStatusMd(context) {
|
|
14
|
-
return `# Status.md
|
|
15
|
-
|
|
16
|
-
## Last Updated: ${new Date().toISOString().split("T")[0]}
|
|
17
|
-
## Session Summary
|
|
18
|
-
Project initialized with ForgeCraft. Tags: ${context.tags.join(", ")}.
|
|
19
|
-
|
|
20
|
-
## Project Structure
|
|
21
|
-
\`\`\`
|
|
22
|
-
[Run 'tree -L 3 --dirsfirst' to populate]
|
|
23
|
-
\`\`\`
|
|
24
|
-
|
|
25
|
-
## Feature Tracker
|
|
26
|
-
| Feature | Status | Branch | Notes |
|
|
27
|
-
|---------|--------|--------|-------|
|
|
28
|
-
| | ⬚ Not Started | | |
|
|
29
|
-
|
|
30
|
-
## Known Bugs
|
|
31
|
-
| ID | Description | Severity | Status |
|
|
32
|
-
|----|-------------|----------|--------|
|
|
33
|
-
| | | | |
|
|
34
|
-
|
|
35
|
-
## Technical Debt
|
|
36
|
-
| Item | Impact | Effort | Priority |
|
|
37
|
-
|------|--------|--------|----------|
|
|
38
|
-
| | | | |
|
|
39
|
-
|
|
40
|
-
## Current Context
|
|
41
|
-
- Working on:
|
|
42
|
-
- Blocked by:
|
|
43
|
-
- Decisions pending:
|
|
44
|
-
- Next steps:
|
|
45
|
-
|
|
46
|
-
## Architecture Decision Log
|
|
47
|
-
| Date | Decision | Rationale | Status |
|
|
48
|
-
|------|----------|-----------|--------|
|
|
49
|
-
| | | | |
|
|
14
|
+
return `# Status.md
|
|
15
|
+
|
|
16
|
+
## Last Updated: ${new Date().toISOString().split("T")[0]}
|
|
17
|
+
## Session Summary
|
|
18
|
+
Project initialized with ForgeCraft. Tags: ${context.tags.join(", ")}.
|
|
19
|
+
|
|
20
|
+
## Project Structure
|
|
21
|
+
\`\`\`
|
|
22
|
+
[Run 'tree -L 3 --dirsfirst' to populate]
|
|
23
|
+
\`\`\`
|
|
24
|
+
|
|
25
|
+
## Feature Tracker
|
|
26
|
+
| Feature | Status | Branch | Notes |
|
|
27
|
+
|---------|--------|--------|-------|
|
|
28
|
+
| | ⬚ Not Started | | |
|
|
29
|
+
|
|
30
|
+
## Known Bugs
|
|
31
|
+
| ID | Description | Severity | Status |
|
|
32
|
+
|----|-------------|----------|--------|
|
|
33
|
+
| | | | |
|
|
34
|
+
|
|
35
|
+
## Technical Debt
|
|
36
|
+
| Item | Impact | Effort | Priority |
|
|
37
|
+
|------|--------|--------|----------|
|
|
38
|
+
| | | | |
|
|
39
|
+
|
|
40
|
+
## Current Context
|
|
41
|
+
- Working on:
|
|
42
|
+
- Blocked by:
|
|
43
|
+
- Decisions pending:
|
|
44
|
+
- Next steps:
|
|
45
|
+
|
|
46
|
+
## Architecture Decision Log
|
|
47
|
+
| Date | Decision | Rationale | Status |
|
|
48
|
+
|------|----------|-----------|--------|
|
|
49
|
+
| | | | |
|
|
50
50
|
`;
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
@@ -56,33 +56,33 @@ Project initialized with ForgeCraft. Tags: ${context.tags.join(", ")}.
|
|
|
56
56
|
* @returns PRD.md content ready to write
|
|
57
57
|
*/
|
|
58
58
|
export function renderPrdSkeleton(context) {
|
|
59
|
-
return `# PRD: ${context.projectName}
|
|
60
|
-
|
|
61
|
-
## Background & Context
|
|
62
|
-
[Why this project exists, what problem it solves]
|
|
63
|
-
|
|
64
|
-
## Stakeholders
|
|
65
|
-
[Who owns it, who uses it, who's affected]
|
|
66
|
-
|
|
67
|
-
## User Stories
|
|
68
|
-
[Organized by feature area]
|
|
69
|
-
- US-001: As a [type], I want [action] so that [benefit]
|
|
70
|
-
|
|
71
|
-
## Requirements
|
|
72
|
-
### Functional Requirements
|
|
73
|
-
- FR-001: [requirement]
|
|
74
|
-
|
|
75
|
-
### Non-Functional Requirements
|
|
76
|
-
[Generated from active tags: ${context.tags.join(", ")}]
|
|
77
|
-
|
|
78
|
-
## Out of Scope
|
|
79
|
-
[Explicitly list what this project does NOT do]
|
|
80
|
-
|
|
81
|
-
## Success Metrics
|
|
82
|
-
[How do we know this project succeeded?]
|
|
83
|
-
|
|
84
|
-
## Open Questions
|
|
85
|
-
[Unresolved decisions]
|
|
59
|
+
return `# PRD: ${context.projectName}
|
|
60
|
+
|
|
61
|
+
## Background & Context
|
|
62
|
+
[Why this project exists, what problem it solves]
|
|
63
|
+
|
|
64
|
+
## Stakeholders
|
|
65
|
+
[Who owns it, who uses it, who's affected]
|
|
66
|
+
|
|
67
|
+
## User Stories
|
|
68
|
+
[Organized by feature area]
|
|
69
|
+
- US-001: As a [type], I want [action] so that [benefit]
|
|
70
|
+
|
|
71
|
+
## Requirements
|
|
72
|
+
### Functional Requirements
|
|
73
|
+
- FR-001: [requirement]
|
|
74
|
+
|
|
75
|
+
### Non-Functional Requirements
|
|
76
|
+
[Generated from active tags: ${context.tags.join(", ")}]
|
|
77
|
+
|
|
78
|
+
## Out of Scope
|
|
79
|
+
[Explicitly list what this project does NOT do]
|
|
80
|
+
|
|
81
|
+
## Success Metrics
|
|
82
|
+
[How do we know this project succeeded?]
|
|
83
|
+
|
|
84
|
+
## Open Questions
|
|
85
|
+
[Unresolved decisions]
|
|
86
86
|
`;
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
@@ -92,35 +92,35 @@ export function renderPrdSkeleton(context) {
|
|
|
92
92
|
* @returns TechSpec.md content ready to write
|
|
93
93
|
*/
|
|
94
94
|
export function renderTechSpecSkeleton(context) {
|
|
95
|
-
return `# Tech Spec: ${context.projectName}
|
|
96
|
-
|
|
97
|
-
## Overview
|
|
98
|
-
[One paragraph translating PRD to technical approach]
|
|
99
|
-
|
|
100
|
-
## Architecture
|
|
101
|
-
### System Diagram
|
|
102
|
-
[Mermaid diagram or description of components]
|
|
103
|
-
|
|
104
|
-
### Tech Stack
|
|
105
|
-
- Runtime: ${context.language}
|
|
106
|
-
- Framework: ${context.framework ?? "[TBD]"}
|
|
107
|
-
|
|
108
|
-
### Data Flow
|
|
109
|
-
[How data moves through the system]
|
|
110
|
-
|
|
111
|
-
## API Contracts
|
|
112
|
-
[Key endpoints, request/response shapes]
|
|
113
|
-
|
|
114
|
-
## Security & Compliance
|
|
115
|
-
[Auth approach, encryption, audit logging]
|
|
116
|
-
|
|
117
|
-
## Dependencies
|
|
118
|
-
[External services, APIs, libraries with version pins]
|
|
119
|
-
|
|
120
|
-
## Risks & Mitigations
|
|
121
|
-
| Risk | Likelihood | Impact | Mitigation |
|
|
122
|
-
|------|-----------|--------|------------|
|
|
123
|
-
| | H/M/L | H/M/L | |
|
|
95
|
+
return `# Tech Spec: ${context.projectName}
|
|
96
|
+
|
|
97
|
+
## Overview
|
|
98
|
+
[One paragraph translating PRD to technical approach]
|
|
99
|
+
|
|
100
|
+
## Architecture
|
|
101
|
+
### System Diagram
|
|
102
|
+
[Mermaid diagram or description of components]
|
|
103
|
+
|
|
104
|
+
### Tech Stack
|
|
105
|
+
- Runtime: ${context.language}
|
|
106
|
+
- Framework: ${context.framework ?? "[TBD]"}
|
|
107
|
+
|
|
108
|
+
### Data Flow
|
|
109
|
+
[How data moves through the system]
|
|
110
|
+
|
|
111
|
+
## API Contracts
|
|
112
|
+
[Key endpoints, request/response shapes]
|
|
113
|
+
|
|
114
|
+
## Security & Compliance
|
|
115
|
+
[Auth approach, encryption, audit logging]
|
|
116
|
+
|
|
117
|
+
## Dependencies
|
|
118
|
+
[External services, APIs, libraries with version pins]
|
|
119
|
+
|
|
120
|
+
## Risks & Mitigations
|
|
121
|
+
| Risk | Likelihood | Impact | Mitigation |
|
|
122
|
+
|------|-----------|--------|------------|
|
|
123
|
+
| | H/M/L | H/M/L | |
|
|
124
124
|
`;
|
|
125
125
|
}
|
|
126
126
|
//# sourceMappingURL=renderer-skeletons.js.map
|
|
@@ -11,12 +11,12 @@ import { appendFileSync, existsSync, mkdirSync, writeFileSync } from "fs";
|
|
|
11
11
|
import { join } from "path";
|
|
12
12
|
// ── Constants ────────────────────────────────────────────────────────
|
|
13
13
|
const GS_SCORE_FILE = "docs/gs-score.md";
|
|
14
|
-
const GS_SCORE_HEADER = `# GS Score Log
|
|
15
|
-
|
|
16
|
-
Tracks S_realized and GS property scores per loop.
|
|
17
|
-
|
|
18
|
-
| date | loop | roadmap_item | s_realized | self-describing | bounded | verifiable | defended | auditable | composable | executable |
|
|
19
|
-
|------|------|--------------|------------|-----------------|---------|-----------|----------|-----------|-----------|-----------|
|
|
14
|
+
const GS_SCORE_HEADER = `# GS Score Log
|
|
15
|
+
|
|
16
|
+
Tracks S_realized and GS property scores per loop.
|
|
17
|
+
|
|
18
|
+
| date | loop | roadmap_item | s_realized | self-describing | bounded | verifiable | defended | auditable | composable | executable |
|
|
19
|
+
|------|------|--------------|------------|-----------------|---------|-----------|----------|-----------|-----------|-----------|
|
|
20
20
|
`;
|
|
21
21
|
const GS_PROPERTY_ORDER = [
|
|
22
22
|
"self-describing",
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool result size utilities.
|
|
3
|
+
*
|
|
4
|
+
* Prevents silent schema truncation at the MCP transport layer by:
|
|
5
|
+
* - Annotating large results with their size (chars + lines)
|
|
6
|
+
* - Truncating results that exceed the limit with an explicit marker
|
|
7
|
+
* so the caller knows to refine their query rather than acting on
|
|
8
|
+
* incomplete data.
|
|
9
|
+
*/
|
|
10
|
+
/** Maximum characters returned in a single tool result. */
|
|
11
|
+
export declare const MAX_TOOL_RESULT_CHARS = 50000;
|
|
12
|
+
/**
|
|
13
|
+
* Annotate a tool result text with its size and truncate if necessary.
|
|
14
|
+
*
|
|
15
|
+
* - Under `maxChars` and over `SIZE_ANNOTATION_THRESHOLD`: appends a compact
|
|
16
|
+
* footer showing char/line count.
|
|
17
|
+
* - Over `maxChars`: truncates to `maxChars` and appends a `[TRUNCATED]`
|
|
18
|
+
* footer so the caller knows the response is incomplete.
|
|
19
|
+
* - Under `SIZE_ANNOTATION_THRESHOLD`: returned as-is (no footer noise for
|
|
20
|
+
* short replies like "No violations recorded.").
|
|
21
|
+
*
|
|
22
|
+
* @param text - Raw tool result text
|
|
23
|
+
* @param maxChars - Truncation limit (default: MAX_TOOL_RESULT_CHARS)
|
|
24
|
+
* @returns Annotated (and possibly truncated) text
|
|
25
|
+
*/
|
|
26
|
+
export declare function annotateResult(text: string, maxChars?: number): string;
|
|
27
|
+
//# sourceMappingURL=result-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-utils.d.ts","sourceRoot":"","sources":["../../src/shared/result-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAK5C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,MAA8B,GACvC,MAAM,CAgBR"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool result size utilities.
|
|
3
|
+
*
|
|
4
|
+
* Prevents silent schema truncation at the MCP transport layer by:
|
|
5
|
+
* - Annotating large results with their size (chars + lines)
|
|
6
|
+
* - Truncating results that exceed the limit with an explicit marker
|
|
7
|
+
* so the caller knows to refine their query rather than acting on
|
|
8
|
+
* incomplete data.
|
|
9
|
+
*/
|
|
10
|
+
/** Maximum characters returned in a single tool result. */
|
|
11
|
+
export const MAX_TOOL_RESULT_CHARS = 50_000;
|
|
12
|
+
/** Minimum size (chars) before a size annotation is appended. */
|
|
13
|
+
const SIZE_ANNOTATION_THRESHOLD = 1_000;
|
|
14
|
+
/**
|
|
15
|
+
* Annotate a tool result text with its size and truncate if necessary.
|
|
16
|
+
*
|
|
17
|
+
* - Under `maxChars` and over `SIZE_ANNOTATION_THRESHOLD`: appends a compact
|
|
18
|
+
* footer showing char/line count.
|
|
19
|
+
* - Over `maxChars`: truncates to `maxChars` and appends a `[TRUNCATED]`
|
|
20
|
+
* footer so the caller knows the response is incomplete.
|
|
21
|
+
* - Under `SIZE_ANNOTATION_THRESHOLD`: returned as-is (no footer noise for
|
|
22
|
+
* short replies like "No violations recorded.").
|
|
23
|
+
*
|
|
24
|
+
* @param text - Raw tool result text
|
|
25
|
+
* @param maxChars - Truncation limit (default: MAX_TOOL_RESULT_CHARS)
|
|
26
|
+
* @returns Annotated (and possibly truncated) text
|
|
27
|
+
*/
|
|
28
|
+
export function annotateResult(text, maxChars = MAX_TOOL_RESULT_CHARS) {
|
|
29
|
+
const total = text.length;
|
|
30
|
+
if (total <= SIZE_ANNOTATION_THRESHOLD)
|
|
31
|
+
return text;
|
|
32
|
+
if (total <= maxChars) {
|
|
33
|
+
const lines = text.split("\n").length;
|
|
34
|
+
return `${text}\n\n---\n_↩ ${total.toLocaleString()} chars · ${lines.toLocaleString()} lines_`;
|
|
35
|
+
}
|
|
36
|
+
const truncated = text.slice(0, maxChars);
|
|
37
|
+
return (`${truncated}\n\n---\n` +
|
|
38
|
+
`_[TRUNCATED: showing first ${maxChars.toLocaleString()} of ${total.toLocaleString()} chars — ` +
|
|
39
|
+
`use a more specific query or smaller scope to see the rest]_`);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=result-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-utils.js","sourceRoot":"","sources":["../../src/shared/result-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,2DAA2D;AAC3D,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE5C,iEAAiE;AACjE,MAAM,yBAAyB,GAAG,KAAK,CAAC;AAExC;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAY,EACZ,WAAmB,qBAAqB;IAExC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;IAE1B,IAAI,KAAK,IAAI,yBAAyB;QAAE,OAAO,IAAI,CAAC;IAEpD,IAAI,KAAK,IAAI,QAAQ,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QACtC,OAAO,GAAG,IAAI,eAAe,KAAK,CAAC,cAAc,EAAE,YAAY,KAAK,CAAC,cAAc,EAAE,SAAS,CAAC;IACjG,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC1C,OAAO,CACL,GAAG,SAAS,WAAW;QACvB,8BAA8B,QAAQ,CAAC,cAAc,EAAE,OAAO,KAAK,CAAC,cAAc,EAAE,WAAW;QAC/F,8DAA8D,CAC/D,CAAC;AACJ,CAAC"}
|
package/dist/tools/add-module.js
CHANGED
|
@@ -60,97 +60,97 @@ function generateTypeScriptModule(moduleDir, moduleName, className, tags) {
|
|
|
60
60
|
const files = [];
|
|
61
61
|
const relBase = `src/modules/${moduleName}`;
|
|
62
62
|
// Types
|
|
63
|
-
const typesContent = `/**
|
|
64
|
-
* ${className} module types.
|
|
65
|
-
*/
|
|
66
|
-
|
|
67
|
-
export interface ${className} {
|
|
68
|
-
readonly id: string;
|
|
69
|
-
// TODO: Define ${className} properties
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export interface Create${className}Input {
|
|
73
|
-
// TODO: Define creation input
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export interface Update${className}Input {
|
|
77
|
-
readonly id: string;
|
|
78
|
-
// TODO: Define update input
|
|
79
|
-
}
|
|
63
|
+
const typesContent = `/**
|
|
64
|
+
* ${className} module types.
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
export interface ${className} {
|
|
68
|
+
readonly id: string;
|
|
69
|
+
// TODO: Define ${className} properties
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface Create${className}Input {
|
|
73
|
+
// TODO: Define creation input
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface Update${className}Input {
|
|
77
|
+
readonly id: string;
|
|
78
|
+
// TODO: Define update input
|
|
79
|
+
}
|
|
80
80
|
`;
|
|
81
81
|
writeFileSync(join(moduleDir, "types.ts"), typesContent);
|
|
82
82
|
files.push(`${relBase}/types.ts`);
|
|
83
83
|
// Interface
|
|
84
|
-
const interfaceContent = `/**
|
|
85
|
-
* ${className} service interface.
|
|
86
|
-
*
|
|
87
|
-
* Defines the contract — implementations are swappable.
|
|
88
|
-
*/
|
|
89
|
-
|
|
90
|
-
import type { ${className}, Create${className}Input, Update${className}Input } from "./types.js";
|
|
91
|
-
|
|
92
|
-
export interface I${className}Service {
|
|
93
|
-
create(input: Create${className}Input): Promise<${className}>;
|
|
94
|
-
findById(id: string): Promise<${className} | null>;
|
|
95
|
-
update(input: Update${className}Input): Promise<${className}>;
|
|
96
|
-
delete(id: string): Promise<void>;
|
|
97
|
-
}
|
|
84
|
+
const interfaceContent = `/**
|
|
85
|
+
* ${className} service interface.
|
|
86
|
+
*
|
|
87
|
+
* Defines the contract — implementations are swappable.
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
import type { ${className}, Create${className}Input, Update${className}Input } from "./types.js";
|
|
91
|
+
|
|
92
|
+
export interface I${className}Service {
|
|
93
|
+
create(input: Create${className}Input): Promise<${className}>;
|
|
94
|
+
findById(id: string): Promise<${className} | null>;
|
|
95
|
+
update(input: Update${className}Input): Promise<${className}>;
|
|
96
|
+
delete(id: string): Promise<void>;
|
|
97
|
+
}
|
|
98
98
|
`;
|
|
99
99
|
writeFileSync(join(moduleDir, "interface.ts"), interfaceContent);
|
|
100
100
|
files.push(`${relBase}/interface.ts`);
|
|
101
101
|
// Service implementation
|
|
102
|
-
const serviceContent = `/**
|
|
103
|
-
* ${className} service implementation.
|
|
104
|
-
*/
|
|
105
|
-
|
|
106
|
-
import type { ${className}, Create${className}Input, Update${className}Input } from "./types.js";
|
|
107
|
-
import type { I${className}Service } from "./interface.js";
|
|
108
|
-
|
|
109
|
-
export class ${className}Service implements I${className}Service {
|
|
110
|
-
async create(input: Create${className}Input): Promise<${className}> {
|
|
111
|
-
// TODO: Implement creation logic
|
|
112
|
-
throw new Error("Not implemented");
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
async findById(id: string): Promise<${className} | null> {
|
|
116
|
-
// TODO: Implement find logic
|
|
117
|
-
throw new Error("Not implemented");
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
async update(input: Update${className}Input): Promise<${className}> {
|
|
121
|
-
// TODO: Implement update logic
|
|
122
|
-
throw new Error("Not implemented");
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
async delete(id: string): Promise<void> {
|
|
126
|
-
// TODO: Implement delete logic
|
|
127
|
-
throw new Error("Not implemented");
|
|
128
|
-
}
|
|
129
|
-
}
|
|
102
|
+
const serviceContent = `/**
|
|
103
|
+
* ${className} service implementation.
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
import type { ${className}, Create${className}Input, Update${className}Input } from "./types.js";
|
|
107
|
+
import type { I${className}Service } from "./interface.js";
|
|
108
|
+
|
|
109
|
+
export class ${className}Service implements I${className}Service {
|
|
110
|
+
async create(input: Create${className}Input): Promise<${className}> {
|
|
111
|
+
// TODO: Implement creation logic
|
|
112
|
+
throw new Error("Not implemented");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async findById(id: string): Promise<${className} | null> {
|
|
116
|
+
// TODO: Implement find logic
|
|
117
|
+
throw new Error("Not implemented");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async update(input: Update${className}Input): Promise<${className}> {
|
|
121
|
+
// TODO: Implement update logic
|
|
122
|
+
throw new Error("Not implemented");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async delete(id: string): Promise<void> {
|
|
126
|
+
// TODO: Implement delete logic
|
|
127
|
+
throw new Error("Not implemented");
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
130
|
`;
|
|
131
131
|
writeFileSync(join(moduleDir, "service.ts"), serviceContent);
|
|
132
132
|
files.push(`${relBase}/service.ts`);
|
|
133
133
|
// Index barrel
|
|
134
|
-
const indexContent = `export type { ${className}, Create${className}Input, Update${className}Input } from "./types.js";
|
|
135
|
-
export type { I${className}Service } from "./interface.js";
|
|
136
|
-
export { ${className}Service } from "./service.js";
|
|
134
|
+
const indexContent = `export type { ${className}, Create${className}Input, Update${className}Input } from "./types.js";
|
|
135
|
+
export type { I${className}Service } from "./interface.js";
|
|
136
|
+
export { ${className}Service } from "./service.js";
|
|
137
137
|
`;
|
|
138
138
|
writeFileSync(join(moduleDir, "index.ts"), indexContent);
|
|
139
139
|
files.push(`${relBase}/index.ts`);
|
|
140
140
|
// API routes if API tag present
|
|
141
141
|
if (tags.includes("API")) {
|
|
142
|
-
const routesContent = `/**
|
|
143
|
-
* ${className} API routes.
|
|
144
|
-
*/
|
|
145
|
-
|
|
146
|
-
// TODO: Register routes with your HTTP framework
|
|
147
|
-
// Example:
|
|
148
|
-
// router.post("/${moduleName}", create${className}Handler);
|
|
149
|
-
// router.get("/${moduleName}/:id", get${className}Handler);
|
|
150
|
-
// router.put("/${moduleName}/:id", update${className}Handler);
|
|
151
|
-
// router.delete("/${moduleName}/:id", delete${className}Handler);
|
|
152
|
-
|
|
153
|
-
export {};
|
|
142
|
+
const routesContent = `/**
|
|
143
|
+
* ${className} API routes.
|
|
144
|
+
*/
|
|
145
|
+
|
|
146
|
+
// TODO: Register routes with your HTTP framework
|
|
147
|
+
// Example:
|
|
148
|
+
// router.post("/${moduleName}", create${className}Handler);
|
|
149
|
+
// router.get("/${moduleName}/:id", get${className}Handler);
|
|
150
|
+
// router.put("/${moduleName}/:id", update${className}Handler);
|
|
151
|
+
// router.delete("/${moduleName}/:id", delete${className}Handler);
|
|
152
|
+
|
|
153
|
+
export {};
|
|
154
154
|
`;
|
|
155
155
|
writeFileSync(join(moduleDir, "routes.ts"), routesContent);
|
|
156
156
|
files.push(`${relBase}/routes.ts`);
|
|
@@ -158,17 +158,17 @@ export {};
|
|
|
158
158
|
// Test file
|
|
159
159
|
const testDir = join(moduleDir, "__tests__");
|
|
160
160
|
mkdirSync(testDir, { recursive: true });
|
|
161
|
-
const testContent = `import { describe, it, expect } from "vitest";
|
|
162
|
-
import { ${className}Service } from "../service.js";
|
|
163
|
-
|
|
164
|
-
describe("${className}Service", () => {
|
|
165
|
-
it("should be defined", () => {
|
|
166
|
-
const service = new ${className}Service();
|
|
167
|
-
expect(service).toBeDefined();
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
// TODO: Add comprehensive tests
|
|
171
|
-
});
|
|
161
|
+
const testContent = `import { describe, it, expect } from "vitest";
|
|
162
|
+
import { ${className}Service } from "../service.js";
|
|
163
|
+
|
|
164
|
+
describe("${className}Service", () => {
|
|
165
|
+
it("should be defined", () => {
|
|
166
|
+
const service = new ${className}Service();
|
|
167
|
+
expect(service).toBeDefined();
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// TODO: Add comprehensive tests
|
|
171
|
+
});
|
|
172
172
|
`;
|
|
173
173
|
writeFileSync(join(testDir, `${moduleName}.test.ts`), testContent);
|
|
174
174
|
files.push(`${relBase}/__tests__/${moduleName}.test.ts`);
|
|
@@ -185,48 +185,48 @@ function generatePythonModule(moduleDir, moduleName, className, _tags) {
|
|
|
185
185
|
writeFileSync(join(moduleDir, "__init__.py"), `"""${className} module."""\n`);
|
|
186
186
|
files.push(`${relBase}/__init__.py`);
|
|
187
187
|
// models.py
|
|
188
|
-
const modelsContent = `"""${className} data models."""
|
|
189
|
-
|
|
190
|
-
from dataclasses import dataclass
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
@dataclass
|
|
194
|
-
class ${className}:
|
|
195
|
-
id: str
|
|
196
|
-
# TODO: Define ${className} fields
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
@dataclass
|
|
200
|
-
class Create${className}Input:
|
|
201
|
-
# TODO: Define creation input
|
|
202
|
-
pass
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
@dataclass
|
|
206
|
-
class Update${className}Input:
|
|
207
|
-
id: str
|
|
208
|
-
# TODO: Define update input
|
|
188
|
+
const modelsContent = `"""${className} data models."""
|
|
189
|
+
|
|
190
|
+
from dataclasses import dataclass
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@dataclass
|
|
194
|
+
class ${className}:
|
|
195
|
+
id: str
|
|
196
|
+
# TODO: Define ${className} fields
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
@dataclass
|
|
200
|
+
class Create${className}Input:
|
|
201
|
+
# TODO: Define creation input
|
|
202
|
+
pass
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
@dataclass
|
|
206
|
+
class Update${className}Input:
|
|
207
|
+
id: str
|
|
208
|
+
# TODO: Define update input
|
|
209
209
|
`;
|
|
210
210
|
writeFileSync(join(moduleDir, "models.py"), modelsContent);
|
|
211
211
|
files.push(`${relBase}/models.py`);
|
|
212
212
|
// service.py
|
|
213
|
-
const serviceContent = `"""${className} service."""
|
|
214
|
-
|
|
215
|
-
from .models import ${className}, Create${className}Input, Update${className}Input
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
class ${className}Service:
|
|
219
|
-
async def create(self, input: Create${className}Input) -> ${className}:
|
|
220
|
-
raise NotImplementedError
|
|
221
|
-
|
|
222
|
-
async def find_by_id(self, id: str) -> ${className} | None:
|
|
223
|
-
raise NotImplementedError
|
|
224
|
-
|
|
225
|
-
async def update(self, input: Update${className}Input) -> ${className}:
|
|
226
|
-
raise NotImplementedError
|
|
227
|
-
|
|
228
|
-
async def delete(self, id: str) -> None:
|
|
229
|
-
raise NotImplementedError
|
|
213
|
+
const serviceContent = `"""${className} service."""
|
|
214
|
+
|
|
215
|
+
from .models import ${className}, Create${className}Input, Update${className}Input
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class ${className}Service:
|
|
219
|
+
async def create(self, input: Create${className}Input) -> ${className}:
|
|
220
|
+
raise NotImplementedError
|
|
221
|
+
|
|
222
|
+
async def find_by_id(self, id: str) -> ${className} | None:
|
|
223
|
+
raise NotImplementedError
|
|
224
|
+
|
|
225
|
+
async def update(self, input: Update${className}Input) -> ${className}:
|
|
226
|
+
raise NotImplementedError
|
|
227
|
+
|
|
228
|
+
async def delete(self, id: str) -> None:
|
|
229
|
+
raise NotImplementedError
|
|
230
230
|
`;
|
|
231
231
|
writeFileSync(join(moduleDir, "service.py"), serviceContent);
|
|
232
232
|
files.push(`${relBase}/service.py`);
|
|
@@ -189,24 +189,24 @@ export function smokeConfigExample(tags) {
|
|
|
189
189
|
if (hasApi) {
|
|
190
190
|
projects.push(" // API smoke uses APIRequestContext — no browser project needed");
|
|
191
191
|
}
|
|
192
|
-
return `
|
|
193
|
-
## Example: playwright.smoke.config.ts
|
|
194
|
-
|
|
195
|
-
\`\`\`typescript
|
|
196
|
-
import { defineConfig${hasBrowser ? ", devices" : ""} } from '@playwright/test';
|
|
197
|
-
|
|
198
|
-
export default defineConfig({
|
|
199
|
-
testMatch: '**/*.smoke.ts',
|
|
200
|
-
retries: 1, // one retry — smoke fail = broken deploy
|
|
201
|
-
timeout: 15_000,
|
|
202
|
-
use: {
|
|
203
|
-
baseURL: process.env['PLAYWRIGHT_BASE_URL'] ?? 'http://localhost:3000',
|
|
204
|
-
// Never run smoke against localhost in CI — use staging URL
|
|
205
|
-
},${hasBrowser ? `\n projects: [\n${projects.join(",\n")}\n ],` : ""}
|
|
206
|
-
});
|
|
207
|
-
\`\`\`
|
|
208
|
-
|
|
209
|
-
Run with: \`npx playwright test --config playwright.smoke.config.ts\`
|
|
192
|
+
return `
|
|
193
|
+
## Example: playwright.smoke.config.ts
|
|
194
|
+
|
|
195
|
+
\`\`\`typescript
|
|
196
|
+
import { defineConfig${hasBrowser ? ", devices" : ""} } from '@playwright/test';
|
|
197
|
+
|
|
198
|
+
export default defineConfig({
|
|
199
|
+
testMatch: '**/*.smoke.ts',
|
|
200
|
+
retries: 1, // one retry — smoke fail = broken deploy
|
|
201
|
+
timeout: 15_000,
|
|
202
|
+
use: {
|
|
203
|
+
baseURL: process.env['PLAYWRIGHT_BASE_URL'] ?? 'http://localhost:3000',
|
|
204
|
+
// Never run smoke against localhost in CI — use staging URL
|
|
205
|
+
},${hasBrowser ? `\n projects: [\n${projects.join(",\n")}\n ],` : ""}
|
|
206
|
+
});
|
|
207
|
+
\`\`\`
|
|
208
|
+
|
|
209
|
+
Run with: \`npx playwright test --config playwright.smoke.config.ts\`
|
|
210
210
|
`;
|
|
211
211
|
}
|
|
212
212
|
//# sourceMappingURL=advice-registry.js.map
|