agentme 0.1.1
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/.github/agents/speckit.analyze.agent.md +184 -0
- package/.github/agents/speckit.checklist.agent.md +295 -0
- package/.github/agents/speckit.clarify.agent.md +181 -0
- package/.github/agents/speckit.constitution.agent.md +84 -0
- package/.github/agents/speckit.implement.agent.md +198 -0
- package/.github/agents/speckit.plan.agent.md +90 -0
- package/.github/agents/speckit.specify.agent.md +237 -0
- package/.github/agents/speckit.tasks.agent.md +200 -0
- package/.github/agents/speckit.taskstoissues.agent.md +30 -0
- package/.github/prompts/speckit.analyze.prompt.md +3 -0
- package/.github/prompts/speckit.checklist.prompt.md +3 -0
- package/.github/prompts/speckit.clarify.prompt.md +3 -0
- package/.github/prompts/speckit.constitution.prompt.md +3 -0
- package/.github/prompts/speckit.implement.prompt.md +3 -0
- package/.github/prompts/speckit.plan.prompt.md +3 -0
- package/.github/prompts/speckit.specify.prompt.md +3 -0
- package/.github/prompts/speckit.tasks.prompt.md +3 -0
- package/.github/prompts/speckit.taskstoissues.prompt.md +3 -0
- package/.specify/memory/constitution.md +119 -0
- package/.specify/scripts/bash/check-prerequisites.sh +190 -0
- package/.specify/scripts/bash/common.sh +253 -0
- package/.specify/scripts/bash/create-new-feature.sh +333 -0
- package/.specify/scripts/bash/setup-plan.sh +73 -0
- package/.specify/scripts/bash/update-agent-context.sh +808 -0
- package/.specify/templates/agent-file-template.md +28 -0
- package/.specify/templates/checklist-template.md +40 -0
- package/.specify/templates/constitution-template.md +50 -0
- package/.specify/templates/plan-template.md +110 -0
- package/.specify/templates/spec-template.md +115 -0
- package/.specify/templates/tasks-template.md +251 -0
- package/.vscode/settings.json +14 -0
- package/.xdrs/agentme/edrs/application/003-javascript-project-tooling.md +89 -0
- package/.xdrs/agentme/edrs/application/010-golang-project-tooling.md +141 -0
- package/.xdrs/agentme/edrs/application/skills/001-create-javascript-project/SKILL.md +360 -0
- package/.xdrs/agentme/edrs/application/skills/003-create-golang-project/SKILL.md +311 -0
- package/.xdrs/agentme/edrs/devops/005-monorepo-structure.md +104 -0
- package/.xdrs/agentme/edrs/devops/006-github-pipelines.md +170 -0
- package/.xdrs/agentme/edrs/devops/008-common-targets.md +207 -0
- package/.xdrs/agentme/edrs/devops/skills/002-monorepo-setup/SKILL.md +270 -0
- package/.xdrs/agentme/edrs/index.md +41 -0
- package/.xdrs/agentme/edrs/observability/011-service-health-check-endpoint.md +78 -0
- package/.xdrs/agentme/edrs/principles/002-coding-best-practices.md +110 -0
- package/.xdrs/agentme/edrs/principles/004-unit-test-requirements.md +97 -0
- package/.xdrs/agentme/edrs/principles/007-project-quality-standards.md +156 -0
- package/.xdrs/agentme/edrs/principles/009-error-handling.md +327 -0
- package/.xdrs/index.md +32 -0
- package/README.md +119 -0
- package/bin/npmdata.js +3 -0
- package/package.json +102 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# agentme-edr-003: JavaScript project tooling and structure
|
|
2
|
+
|
|
3
|
+
## Context and Problem Statement
|
|
4
|
+
|
|
5
|
+
JavaScript/TypeScript projects accumulate inconsistent tooling configurations, making onboarding, quality enforcement, and cross-project maintenance unnecessarily hard.
|
|
6
|
+
|
|
7
|
+
What tooling and project structure should JavaScript/TypeScript projects follow to ensure consistency, quality, and ease of development?
|
|
8
|
+
|
|
9
|
+
## Decision Outcome
|
|
10
|
+
|
|
11
|
+
**Use pnpm, tsc, esbuild, eslint, and jest with a standard layout separating library code (`lib/`) from runnable usage examples (`examples/`), coordinated by root-level Makefiles.**
|
|
12
|
+
|
|
13
|
+
Clear, consistent tooling and layout enable fast onboarding, reliable CI pipelines, and a predictable developer experience across projects.
|
|
14
|
+
|
|
15
|
+
### Implementation Details
|
|
16
|
+
|
|
17
|
+
#### Tooling
|
|
18
|
+
|
|
19
|
+
| Tool | Purpose |
|
|
20
|
+
|------|---------|
|
|
21
|
+
| **pnpm** | Package manager — strict linking, workspace support, fast installs |
|
|
22
|
+
| **tsc** | TypeScript compilation — type checking, declaration generation |
|
|
23
|
+
| **esbuild** | Bundling — fast bundling for distribution or single-binary outputs |
|
|
24
|
+
| **eslint** | Linting — code style and quality enforcement |
|
|
25
|
+
| **jest** | Testing — unit and integration test runner |
|
|
26
|
+
|
|
27
|
+
All commands are run exclusively through Makefiles, not through `package.json` scripts.
|
|
28
|
+
|
|
29
|
+
#### ESLint
|
|
30
|
+
|
|
31
|
+
Use `@stutzlab/eslint-config` as the base ESLint config. Use ESLint 9 flat config format (`lib/eslint.config.js`).
|
|
32
|
+
|
|
33
|
+
#### Project structure
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
/ # workspace root
|
|
37
|
+
├── Makefile # delegates build/lint/test to /lib and /examples
|
|
38
|
+
├── README.md # Quick Start first; used as npm registry page
|
|
39
|
+
├── lib/ # the published npm package
|
|
40
|
+
│ ├── Makefile # build, lint, test, publish targets
|
|
41
|
+
│ ├── package.json # package manifest
|
|
42
|
+
│ ├── tsconfig.json # TypeScript config
|
|
43
|
+
│ ├── jest.config.js # Jest config
|
|
44
|
+
│ ├── eslint.config.js # ESLint config (ESLint 9 flat config)
|
|
45
|
+
│ └── src/ # all TypeScript source files
|
|
46
|
+
│ ├── index.ts # public API re-exports
|
|
47
|
+
│ └── *.test.ts # test files co-located with source
|
|
48
|
+
└── examples/ # runnable usage examples
|
|
49
|
+
├── Makefile # build + test all examples in sequence
|
|
50
|
+
├── usage-x/ # first example
|
|
51
|
+
│ └── package.json
|
|
52
|
+
└── usage-y/ # second example
|
|
53
|
+
└── package.json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The root `Makefile` delegates every target to `/lib` then `/examples` in sequence.
|
|
57
|
+
|
|
58
|
+
#### lib/Makefile targets
|
|
59
|
+
|
|
60
|
+
| Target | Description |
|
|
61
|
+
|--------|-------------|
|
|
62
|
+
| `install` | `pnpm install --frozen-lockfile` |
|
|
63
|
+
| `build` | compile with `tsc`, strip test files from `dist/`, then `pnpm pack` for local use by examples |
|
|
64
|
+
| `build-module` | compile with `tsc` only (no pack) |
|
|
65
|
+
| `lint` | `pnpm exec eslint ./src` |
|
|
66
|
+
| `lint-fix` | `pnpm exec eslint ./src --fix` |
|
|
67
|
+
| `test` | `pnpm exec jest --verbose` |
|
|
68
|
+
| `test-watch` | `pnpm exec jest --watch` |
|
|
69
|
+
| `clean` | remove `node_modules/` and `dist/` |
|
|
70
|
+
| `all` | `build lint test` |
|
|
71
|
+
| `publish` | version-bump with `monotag`, then `npm publish --provenance` |
|
|
72
|
+
|
|
73
|
+
#### lib/package.json key fields
|
|
74
|
+
|
|
75
|
+
- `"main"`: `dist/index.js`
|
|
76
|
+
- `"types"`: `dist/index.d.ts`
|
|
77
|
+
- `"files"`: `["dist/**", "package.json", "README.md"]`
|
|
78
|
+
- `"scripts"`: empty — all commands are driven by the Makefile
|
|
79
|
+
|
|
80
|
+
#### examples/
|
|
81
|
+
|
|
82
|
+
Each sub-folder under `examples/` is an independent package. The Makefile installs the locally built `.tgz` pack from `lib/dist/` so examples simulate real external usage.
|
|
83
|
+
|
|
84
|
+
The examples folder MUST exist for any libraries and utilities that are published or have more than 500 lines of code
|
|
85
|
+
|
|
86
|
+
### Related Skills
|
|
87
|
+
|
|
88
|
+
- [001-create-javascript-project](skills/001-create-javascript-project/SKILL.md) — scaffolds a new project following this structure
|
|
89
|
+
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# agentme-edr-010: Go project tooling and structure
|
|
2
|
+
|
|
3
|
+
## Context and Problem Statement
|
|
4
|
+
|
|
5
|
+
Go (Golang) projects often diverge in their module layout, tooling conventions, and build processes, making cross-project onboarding slow and CI pipelines hard to standardize. Without clear decisions on linting, testing, binary distribution, and package structure, teams repeatedly reinvent the same scaffolding.
|
|
6
|
+
|
|
7
|
+
What tooling and project structure should Go projects follow to ensure consistency, quality, and ease of development?
|
|
8
|
+
|
|
9
|
+
## Decision Outcome
|
|
10
|
+
|
|
11
|
+
**Use the standard Go toolchain (`go build`, `go test`) with `golangci-lint` for linting, feature packages in subdirectories (no `internal/` by default), a `cli/` package for command wiring, and a Makefile as the single entry point for all development tasks, with the Go toolchain and related CLIs sourced from the repository's Mise-managed environment when the repository defines `.mise.toml`.**
|
|
12
|
+
|
|
13
|
+
A predictable layout and minimal external tooling keep Go projects approachable, fast to build, and easy to distribute as cross-platform binaries.
|
|
14
|
+
|
|
15
|
+
### Implementation Details
|
|
16
|
+
|
|
17
|
+
#### Tooling
|
|
18
|
+
|
|
19
|
+
| Tool | Purpose |
|
|
20
|
+
|------|---------|
|
|
21
|
+
| **go toolchain** | Compilation, testing, formatting (`go build`, `go test`, `go fmt`, `go vet`, `go mod`) |
|
|
22
|
+
| **golangci-lint** | Linting — aggregates many linters in one fast run; configured via `.golangci.yml` |
|
|
23
|
+
| **monotag** | Version tagging from git history for the `publish` target |
|
|
24
|
+
|
|
25
|
+
All commands are run exclusively through the Makefile, never ad-hoc.
|
|
26
|
+
When the repository has a root `.mise.toml`, `go`, `golangci-lint`, and any other Go-related CLIs used by the project **MUST** be pinned there and resolved from the Mise-managed environment rather than the host machine.
|
|
27
|
+
Direct installation of project-required Go CLIs with `go install ...@latest` as a repair step is **NOT** allowed unless an XDR for that repository explicitly permits it.
|
|
28
|
+
|
|
29
|
+
#### Project structure
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
/ # project root (single Go module)
|
|
33
|
+
├── Makefile # build, lint, test, publish, and utility targets
|
|
34
|
+
├── go.mod # module declaration (github.com/<owner>/<project>)
|
|
35
|
+
├── go.sum # locked dependency checksums
|
|
36
|
+
├── main.go # binary entry point — argument dispatch only, no logic
|
|
37
|
+
├── .golangci.yml # golangci-lint configuration
|
|
38
|
+
├── .gitignore
|
|
39
|
+
├── README.md
|
|
40
|
+
├── <feature-a>/ # domain package (e.g. ownership/, changes/, utils/)
|
|
41
|
+
│ ├── *.go # business logic
|
|
42
|
+
│ └── *_test.go # unit tests co-located with source
|
|
43
|
+
├── <feature-b>/
|
|
44
|
+
│ └── ...
|
|
45
|
+
└── cli/ # CLI wiring — ties flags to domain packages
|
|
46
|
+
├── <feature-a>/
|
|
47
|
+
│ └── *.go
|
|
48
|
+
└── <feature-b>/
|
|
49
|
+
└── *.go
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Key layout rules:**
|
|
53
|
+
|
|
54
|
+
- One Go module per project (`go.mod` at the project root). In a monorepo, each Go project has its own `go.mod` in its subdirectory. No nested modules within a single project unless explicitly justified.
|
|
55
|
+
- `main.go` is solely an argument dispatcher — it reads `os.Args[1]` and delegates to a `cli/<feature>/Run*()` function. No domain logic lives in `main.go`.
|
|
56
|
+
- Business logic lives in named feature packages at the root (e.g., `ownership/`, `changes/`, `utils/`). These packages are importable and testable without any CLI concerns.
|
|
57
|
+
- `cli/` packages own flag parsing, output formatting, and the wiring between flags and domain functions. No business logic lives in `cli/`.
|
|
58
|
+
- Packages are flat by default; sub-packages are only introduced when a feature package itself exceeds ~400 lines or has clearly separable sub-concerns.
|
|
59
|
+
|
|
60
|
+
#### go.mod
|
|
61
|
+
|
|
62
|
+
- Module path: `github.com/<owner>/<project>` (or the relevant VCS path for the project)
|
|
63
|
+
- Use the latest stable Go version (e.g. `go 1.24`).
|
|
64
|
+
- Separate `require` blocks: direct dependencies first, then `// indirect` dependencies.
|
|
65
|
+
- If the repository uses Mise, the Go version declared in `go.mod` and the Go version pinned in `.mise.toml` **MUST** stay aligned.
|
|
66
|
+
|
|
67
|
+
#### Makefile targets
|
|
68
|
+
|
|
69
|
+
| Target | Description |
|
|
70
|
+
|--------|-------------|
|
|
71
|
+
| `all` | Default; runs `build lint test` in sequence |
|
|
72
|
+
| `build` | `go mod download && go build -o dist/<binary>` |
|
|
73
|
+
| `build-all` | Cross-compile for all target platforms (darwin/linux/windows × amd64/arm64) |
|
|
74
|
+
| `build-arch-os` | Compile for a specific `OS` and `ARCH` environment variable pair; output to `dist/${OS}-${ARCH}/<binary>` |
|
|
75
|
+
| `install` | `go mod download` |
|
|
76
|
+
| `lint` | `golangci-lint run ./...` |
|
|
77
|
+
| `lint-fix` | `golangci-lint run --fix ./...` |
|
|
78
|
+
| `test` | `go test -cover ./...` — runs all tests with coverage |
|
|
79
|
+
| `test-unit` | `go test -cover ./...` — alias for unit tests only (same here; integration tests get a separate tag) |
|
|
80
|
+
| `coverage` | `go tool cover -func ./coverage.out` — displays coverage summary |
|
|
81
|
+
| `clean` | Remove `dist/` and any coverage files |
|
|
82
|
+
| `start` | `go run ./ <default-args>` — launch the binary locally for dev use |
|
|
83
|
+
| `publish` | Tag with `monotag`, then push tag + binaries to GitHub Releases |
|
|
84
|
+
|
|
85
|
+
When the repository uses Mise, the intended invocation pattern is:
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
mise install
|
|
89
|
+
mise exec -- make build
|
|
90
|
+
mise exec -- make test
|
|
91
|
+
mise exec -- make lint
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Using `make build`, `make test`, or `make lint` from an already activated Mise shell is equivalent.
|
|
95
|
+
|
|
96
|
+
#### Cross-platform binary distribution
|
|
97
|
+
|
|
98
|
+
When the project produces a CLI binary for end-users:
|
|
99
|
+
|
|
100
|
+
- Build separate binaries for: `darwin/amd64`, `darwin/arm64`, `linux/amd64`, `linux/arm64`, `windows/amd64`.
|
|
101
|
+
- Use `GOOS`, `GOARCH`, and `CGO_ENABLED=0` to produce fully static binaries.
|
|
102
|
+
- Store outputs under `dist/${OS}-${ARCH}/<binary-name>`.
|
|
103
|
+
- Optionally wrap binaries in npm packages (one package per platform) for distribution via `npx`. Each npm package contains only the binary for its platform; a meta-package with a `bin/` entry that delegates to the correct platform package is added at the root of the npm folder.
|
|
104
|
+
|
|
105
|
+
#### Testing
|
|
106
|
+
|
|
107
|
+
- Tests are co-located with source: `<feature>/<file>_test.go`.
|
|
108
|
+
- Use `github.com/stretchr/testify` (`assert`, `require`) for test assertions.
|
|
109
|
+
- Run all tests: `go test -cover ./...`
|
|
110
|
+
- Benchmarks: `go test -bench . -benchmem -count 20`
|
|
111
|
+
- Integration or slow tests: guard with `//go:build integration` and skip in unit runs via `-tags=unit`.
|
|
112
|
+
|
|
113
|
+
#### Linting
|
|
114
|
+
|
|
115
|
+
Configure `.golangci.yml` with at minimum:
|
|
116
|
+
|
|
117
|
+
```yaml
|
|
118
|
+
linters:
|
|
119
|
+
enable:
|
|
120
|
+
- errcheck
|
|
121
|
+
- govet
|
|
122
|
+
- staticcheck
|
|
123
|
+
- unused
|
|
124
|
+
- gosimple
|
|
125
|
+
- ineffassign
|
|
126
|
+
- typecheck
|
|
127
|
+
run:
|
|
128
|
+
timeout: 5m
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### Logging
|
|
132
|
+
|
|
133
|
+
Use `github.com/sirupsen/logrus` for structured logging. Set the log level from a `--verbose` CLI flag, defaulting to `false` / `WarnLevel`. Do not use `fmt.Println` for diagnostic output.
|
|
134
|
+
|
|
135
|
+
#### CLI flag parsing
|
|
136
|
+
|
|
137
|
+
Use the standard library `flag` package for CLI flags. Each `cli/<feature>` package defines its own `FlagSet`, parses it from `os.Args[2:]`, and calls the corresponding domain function.
|
|
138
|
+
|
|
139
|
+
### Related Skills
|
|
140
|
+
|
|
141
|
+
- [003-create-golang-project](skills/003-create-golang-project/SKILL.md) — scaffolds a new Go project following this structure
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: 001-create-javascript-project
|
|
3
|
+
description: >
|
|
4
|
+
Scaffolds the initial boilerplate structure for a JavaScript/TypeScript library project following
|
|
5
|
+
the standard tooling and layout defined in _core-edr-003. Activate this skill when the user
|
|
6
|
+
asks to create, scaffold, or initialize a new JavaScript or TypeScript library project, npm
|
|
7
|
+
package, or similar project structure.
|
|
8
|
+
metadata:
|
|
9
|
+
author: flaviostutz
|
|
10
|
+
version: "1.0"
|
|
11
|
+
compatibility: JavaScript/TypeScript, Node.js 18+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
Creates a complete JavaScript/TypeScript library project from scratch. The layout separates
|
|
17
|
+
library source (`lib/`) from runnable usage examples (`examples/`), coordinated by root-level
|
|
18
|
+
Makefiles. Boilerplate is derived from the [npmdata](https://github.com/flaviostutz/npmdata)
|
|
19
|
+
project.
|
|
20
|
+
|
|
21
|
+
Related EDR: [agentme-edr-003](../../003-javascript-project-tooling.md)
|
|
22
|
+
|
|
23
|
+
## Instructions
|
|
24
|
+
|
|
25
|
+
### Phase 1: Gather information
|
|
26
|
+
|
|
27
|
+
1. Ask for (or infer from context):
|
|
28
|
+
- **Package name** (npm-compatible, e.g. `my-lib`)
|
|
29
|
+
- **Short description** (one sentence)
|
|
30
|
+
- **Author** name or GitHub username
|
|
31
|
+
- **Node.js version** (default: `24`)
|
|
32
|
+
- **GitHub repo URL** (optional, for `package.json` fields)
|
|
33
|
+
2. Confirm the target directory (default: current workspace root).
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
### Phase 2: Create root files
|
|
38
|
+
|
|
39
|
+
**`./Makefile`**
|
|
40
|
+
|
|
41
|
+
Delegates every make target to `/lib` then `/examples` in sequence:
|
|
42
|
+
|
|
43
|
+
```makefile
|
|
44
|
+
SHELL := /bin/bash
|
|
45
|
+
%:
|
|
46
|
+
@echo ''
|
|
47
|
+
@echo '>>> Running /lib:$@...'
|
|
48
|
+
@cd lib && make $@
|
|
49
|
+
@echo ''
|
|
50
|
+
@echo '>>> Running /examples:$@...'
|
|
51
|
+
@cd examples && STAGE=dev make $@
|
|
52
|
+
|
|
53
|
+
publish:
|
|
54
|
+
cd lib && make publish
|
|
55
|
+
|
|
56
|
+
prepare:
|
|
57
|
+
@echo "Run 'nvm use; corepack enable'"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**`./.nvmrc`**
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
24
|
|
64
|
+
```
|
|
65
|
+
(Replace `24` with the chosen Node.js version.)
|
|
66
|
+
|
|
67
|
+
**`./.gitignore`**
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
node_modules/
|
|
71
|
+
dist/
|
|
72
|
+
*.tgz
|
|
73
|
+
.npmdata
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
### Phase 3: Create `lib/`
|
|
79
|
+
|
|
80
|
+
**`lib/src/index.ts`** — public API entry point:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
export const hello = (name: string): string => {
|
|
84
|
+
return `Hello, ${name}!`;
|
|
85
|
+
};
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**`lib/src/index.test.ts`** — co-located unit test:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { hello } from './index';
|
|
92
|
+
|
|
93
|
+
describe('hello', () => {
|
|
94
|
+
it('should return a greeting', () => {
|
|
95
|
+
expect(hello('world')).toBe('Hello, world!');
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**`lib/Makefile`**:
|
|
101
|
+
|
|
102
|
+
```makefile
|
|
103
|
+
SHELL := /bin/bash
|
|
104
|
+
|
|
105
|
+
build: install
|
|
106
|
+
@rm -rf dist
|
|
107
|
+
pnpm exec tsc --outDir dist
|
|
108
|
+
@-find ./dist \( -regex '.*\.test\..*' -o -regex '.*__tests.*' \) -exec rm -rf {} \; 2> /dev/null
|
|
109
|
+
@# Create pack for use by examples to simulate real external usage
|
|
110
|
+
pnpm pack --pack-destination dist
|
|
111
|
+
|
|
112
|
+
build-module: install
|
|
113
|
+
@rm -rf dist
|
|
114
|
+
pnpm exec tsc --outDir dist
|
|
115
|
+
@-find ./dist \( -regex '.*\.test\..*' -o -regex '.*__tests.*' \) -exec rm -rf {} \; 2> /dev/null
|
|
116
|
+
|
|
117
|
+
lint:
|
|
118
|
+
pnpm exec eslint ./src --ext .ts
|
|
119
|
+
|
|
120
|
+
lint-fix:
|
|
121
|
+
pnpm exec eslint . --ext .ts --fix
|
|
122
|
+
|
|
123
|
+
test-watch:
|
|
124
|
+
pnpm exec jest --watch
|
|
125
|
+
|
|
126
|
+
test:
|
|
127
|
+
pnpm exec jest --verbose
|
|
128
|
+
|
|
129
|
+
clean:
|
|
130
|
+
rm -rf node_modules
|
|
131
|
+
rm -rf dist
|
|
132
|
+
|
|
133
|
+
all: build lint test
|
|
134
|
+
|
|
135
|
+
install:
|
|
136
|
+
pnpm install --frozen-lockfile --config.dedupe-peer-dependents=false
|
|
137
|
+
|
|
138
|
+
publish:
|
|
139
|
+
npx -y monotag@1.26.0 current --bump-action=latest --prefix=
|
|
140
|
+
@VERSION=$$(node -p "require('./package.json').version"); \
|
|
141
|
+
if echo "$$VERSION" | grep -q '-'; then \
|
|
142
|
+
TAG=$$(echo "$$VERSION" | sed 's/[0-9]*\.[0-9]*\.[0-9]*-\([a-zA-Z][a-zA-Z0-9]*\).*/\1/'); \
|
|
143
|
+
echo "Prerelease version $$VERSION detected, publishing with --tag $$TAG"; \
|
|
144
|
+
npm publish --no-git-checks --provenance --tag "$$TAG"; \
|
|
145
|
+
else \
|
|
146
|
+
npm publish --no-git-checks --provenance; \
|
|
147
|
+
fi
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**`lib/package.json`** (replace `[package-name]`, `[description]`, `[author]`, `[owner]`, `[repo]`):
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"name": "[package-name]",
|
|
155
|
+
"version": "0.0.1",
|
|
156
|
+
"description": "[description]",
|
|
157
|
+
"main": "dist/index.js",
|
|
158
|
+
"types": "dist/index.d.ts",
|
|
159
|
+
"files": [
|
|
160
|
+
"dist/**",
|
|
161
|
+
"package.json",
|
|
162
|
+
"README.md"
|
|
163
|
+
],
|
|
164
|
+
"packageManager": "pnpm@8.9.0",
|
|
165
|
+
"scripts": {},
|
|
166
|
+
"repository": {
|
|
167
|
+
"type": "git",
|
|
168
|
+
"url": "git+https://github.com/[owner]/[repo].git"
|
|
169
|
+
},
|
|
170
|
+
"author": "[author]",
|
|
171
|
+
"license": "MIT",
|
|
172
|
+
"bugs": {
|
|
173
|
+
"url": "https://github.com/[owner]/[repo]/issues"
|
|
174
|
+
},
|
|
175
|
+
"homepage": "https://github.com/[owner]/[repo]#readme",
|
|
176
|
+
"devDependencies": {
|
|
177
|
+
"@babel/preset-typescript": "^7.21.0",
|
|
178
|
+
"@stutzlab/eslint-config": "^3.2.1",
|
|
179
|
+
"@tsconfig/node24": "^24.0.0",
|
|
180
|
+
"@types/jest": "^29.5.0",
|
|
181
|
+
"esbuild": "^0.20.0",
|
|
182
|
+
"eslint": "^8.57.0",
|
|
183
|
+
"jest": "^29.7.0",
|
|
184
|
+
"ts-jest": "^29.1.0",
|
|
185
|
+
"typescript": "^5.3.0"
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**`lib/tsconfig.json`**:
|
|
191
|
+
|
|
192
|
+
```json
|
|
193
|
+
{
|
|
194
|
+
"extends": "@tsconfig/node24/tsconfig.json",
|
|
195
|
+
"compilerOptions": {
|
|
196
|
+
"outDir": "dist",
|
|
197
|
+
"rootDir": "src",
|
|
198
|
+
"declaration": true,
|
|
199
|
+
"declarationMap": true,
|
|
200
|
+
"sourceMap": true
|
|
201
|
+
},
|
|
202
|
+
"include": ["src/**/*"],
|
|
203
|
+
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**`lib/jest.config.js`**:
|
|
208
|
+
|
|
209
|
+
```javascript
|
|
210
|
+
module.exports = {
|
|
211
|
+
preset: 'ts-jest',
|
|
212
|
+
testEnvironment: 'node',
|
|
213
|
+
testMatch: ['**/*.test.ts'],
|
|
214
|
+
collectCoverageFrom: ['src/**/*.ts', '!src/**/*.test.ts'],
|
|
215
|
+
};
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**`lib/eslint.config.js`** (ESLint 9 flat config format):
|
|
219
|
+
|
|
220
|
+
```js
|
|
221
|
+
import baseConfig from '@stutzlab/eslint-config';
|
|
222
|
+
|
|
223
|
+
export default [
|
|
224
|
+
...baseConfig,
|
|
225
|
+
{
|
|
226
|
+
languageOptions: {
|
|
227
|
+
parserOptions: {
|
|
228
|
+
project: ['./tsconfig.json'],
|
|
229
|
+
tsconfigRootDir: process.cwd(),
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
];
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
### Phase 4: Create `examples/`
|
|
239
|
+
|
|
240
|
+
**`examples/Makefile`** (replace `[package-name]`):
|
|
241
|
+
|
|
242
|
+
```makefile
|
|
243
|
+
SHELL := /bin/bash
|
|
244
|
+
%:
|
|
245
|
+
@echo "Unknown target: $@. Ignoring"
|
|
246
|
+
|
|
247
|
+
build: install
|
|
248
|
+
@echo "Examples built"
|
|
249
|
+
|
|
250
|
+
install:
|
|
251
|
+
# Replace the lib dependency with the locally built pack
|
|
252
|
+
pnpm add [package-name]@file:../lib/dist/[package-name]-0.0.1.tgz
|
|
253
|
+
pnpm install
|
|
254
|
+
|
|
255
|
+
test:
|
|
256
|
+
@echo "Running example tests..."
|
|
257
|
+
cd usage-basic && node index.js
|
|
258
|
+
|
|
259
|
+
all: build test
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**`examples/usage-basic/package.json`** (replace `[package-name]`):
|
|
263
|
+
|
|
264
|
+
```json
|
|
265
|
+
{
|
|
266
|
+
"name": "usage-basic",
|
|
267
|
+
"version": "1.0.0",
|
|
268
|
+
"description": "Basic usage example for [package-name]",
|
|
269
|
+
"type": "module",
|
|
270
|
+
"scripts": {},
|
|
271
|
+
"dependencies": {
|
|
272
|
+
"[package-name]": "file:../../lib/dist/[package-name]-0.0.1.tgz"
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**`examples/usage-basic/index.js`**:
|
|
278
|
+
|
|
279
|
+
```javascript
|
|
280
|
+
import { hello } from '[package-name]';
|
|
281
|
+
|
|
282
|
+
const result = hello('world');
|
|
283
|
+
console.log(result);
|
|
284
|
+
// expected output: Hello, world!
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
### Phase 5: Create `README.md`
|
|
290
|
+
|
|
291
|
+
Quick Start must appear at the top — it is rendered first on the npm registry page.
|
|
292
|
+
|
|
293
|
+
```markdown
|
|
294
|
+
# [package-name]
|
|
295
|
+
|
|
296
|
+
[description]
|
|
297
|
+
|
|
298
|
+
## Quick Start
|
|
299
|
+
|
|
300
|
+
\`\`\`bash
|
|
301
|
+
pnpm add [package-name]
|
|
302
|
+
\`\`\`
|
|
303
|
+
|
|
304
|
+
\`\`\`typescript
|
|
305
|
+
import { hello } from '[package-name]';
|
|
306
|
+
|
|
307
|
+
const greeting = hello('world');
|
|
308
|
+
console.log(greeting); // Hello, world!
|
|
309
|
+
\`\`\`
|
|
310
|
+
|
|
311
|
+
## Installation
|
|
312
|
+
|
|
313
|
+
\`\`\`bash
|
|
314
|
+
npm install [package-name]
|
|
315
|
+
# or
|
|
316
|
+
pnpm add [package-name]
|
|
317
|
+
\`\`\`
|
|
318
|
+
|
|
319
|
+
## Examples
|
|
320
|
+
|
|
321
|
+
See the [examples/](examples/) folder for complete runnable examples.
|
|
322
|
+
|
|
323
|
+
## License
|
|
324
|
+
|
|
325
|
+
MIT
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
### Phase 6: Verify
|
|
331
|
+
|
|
332
|
+
Review all created files and confirm:
|
|
333
|
+
|
|
334
|
+
- [ ] Root `Makefile` delegates to both `lib/` and `examples/`
|
|
335
|
+
- [ ] `lib/src/index.ts` exports at least one symbol
|
|
336
|
+
- [ ] `lib/src/index.test.ts` has at least one passing test
|
|
337
|
+
- [ ] `lib/package.json` has `main`, `types`, and `files` set correctly
|
|
338
|
+
- [ ] `README.md` starts with Quick Start containing a code example
|
|
339
|
+
- [ ] All `[package-name]` placeholders are replaced with the actual name
|
|
340
|
+
- [ ] Structure matches the layout in [_core-edr-003](../../003-javascript-project-tooling.md)
|
|
341
|
+
|
|
342
|
+
## Examples
|
|
343
|
+
|
|
344
|
+
**User:** "Create a new TypeScript library project called `retry-client`"
|
|
345
|
+
|
|
346
|
+
**Agent action:** Gathers: name=`retry-client`, default Node.js 24, then creates:
|
|
347
|
+
- `./Makefile`, `./.nvmrc`, `./.gitignore`
|
|
348
|
+
- `lib/src/index.ts`, `lib/src/index.test.ts`, `lib/Makefile`, `lib/package.json`, `lib/tsconfig.json`, `lib/jest.config.js`, `lib/eslint.config.js`
|
|
349
|
+
- `examples/Makefile`, `examples/usage-basic/package.json`, `examples/usage-basic/index.js`
|
|
350
|
+
- `README.md` (Quick Start first)
|
|
351
|
+
|
|
352
|
+
All `[package-name]` replaced with `retry-client`.
|
|
353
|
+
|
|
354
|
+
## Edge Cases
|
|
355
|
+
|
|
356
|
+
- **Existing files** — skip creation; adapt references to the existing structure
|
|
357
|
+
- **Different Node.js version** — update `.nvmrc` and `tsconfig.json` `extends` (e.g. `@tsconfig/node22`)
|
|
358
|
+
- **CLI tool** — add `"bin": "dist/main.js"` to `package.json` and create `lib/src/main.ts` as the CLI entry point; add `esbuild` bundle target in `lib/Makefile`
|
|
359
|
+
- **No examples needed** — omit the `examples/` directory; remove the `examples` delegation from root `Makefile`
|
|
360
|
+
- **Binary bundling (Lambda/browser)** — add an esbuild step to `lib/Makefile`: `pnpm exec esbuild src/main.ts --bundle --platform=node --outfile=dist/bundle.js`
|