@outcomeeng/spx 0.1.8 → 0.3.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 +68 -41
- package/bin/spx.js +17 -20
- package/dist/cli.js +2112 -400
- package/dist/cli.js.map +1 -1
- package/package.json +27 -17
package/README.md
CHANGED
|
@@ -4,14 +4,16 @@ Developer CLI for code validation and session management.
|
|
|
4
4
|
|
|
5
5
|
## What is spx?
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
`spx` is a command-line interface (CLI) tool that provides code validation and session management for projects that implement the spec-as-source methodology named [Outcome Engineering](https://outcome.engineering). The `spx` CLI works hand-in-hand with the **Claude Code** and **Codex** [plugin marketplace for Outcome Engineering](https://github.com/outcomeeng/plugins).
|
|
8
|
+
|
|
9
|
+
The `spx` CLI orchestrates linting, type checking, circular dependency detection, markdown validation, literal reuse checks, and work handoffs between agent contexts.
|
|
8
10
|
|
|
9
11
|
### Key Benefits
|
|
10
12
|
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
13
|
+
- Run the full quality gate through a single `spx validation all` command
|
|
14
|
+
- Queue, claim, and hand off work between agents with `spx session`
|
|
15
|
+
- Text and JSON output for CI and automation
|
|
16
|
+
- OIDC Trusted Publishing with Sigstore provenance via GitHub Actions
|
|
15
17
|
|
|
16
18
|
All commands are domain-scoped (e.g., `spx validation`, `spx session`) and support `--quiet` and `--json` flags for CI and automation.
|
|
17
19
|
|
|
@@ -35,18 +37,22 @@ pnpm link --global
|
|
|
35
37
|
### Code Validation
|
|
36
38
|
|
|
37
39
|
```bash
|
|
38
|
-
# Full validation pipeline
|
|
40
|
+
# Full validation pipeline
|
|
39
41
|
spx validation all
|
|
40
42
|
|
|
41
43
|
# Individual checks
|
|
42
|
-
spx validation lint
|
|
43
|
-
spx validation lint --fix
|
|
44
|
-
spx validation typescript
|
|
45
|
-
spx validation circular
|
|
46
|
-
spx validation knip
|
|
47
|
-
|
|
48
|
-
#
|
|
49
|
-
|
|
44
|
+
spx validation lint # ESLint
|
|
45
|
+
spx validation lint --fix # ESLint with auto-fix
|
|
46
|
+
spx validation typescript # TypeScript type checking (alias: spx validation ts)
|
|
47
|
+
spx validation circular # Circular dependency detection
|
|
48
|
+
spx validation knip # Unused code detection
|
|
49
|
+
spx validation markdown # Markdown link validation (alias: spx validation md)
|
|
50
|
+
spx validation literal # Source/test literal reuse detection
|
|
51
|
+
|
|
52
|
+
# Scope and targeting
|
|
53
|
+
spx validation all --scope production # Exclude tests/scripts
|
|
54
|
+
spx validation all --fix # Auto-fix across all checks
|
|
55
|
+
spx validation all --files src/session/ # Validate specific files or directories
|
|
50
56
|
```
|
|
51
57
|
|
|
52
58
|
All validation commands support `--quiet` for CI and `--json` for machine-readable output.
|
|
@@ -67,15 +73,24 @@ EOF
|
|
|
67
73
|
# List all sessions
|
|
68
74
|
spx session list
|
|
69
75
|
|
|
76
|
+
# List todo sessions only
|
|
77
|
+
spx session todo
|
|
78
|
+
|
|
70
79
|
# Claim the highest priority session
|
|
71
80
|
spx session pickup --auto
|
|
72
81
|
|
|
73
|
-
# Release
|
|
74
|
-
spx session release
|
|
82
|
+
# Release one or more sessions back to the todo queue
|
|
83
|
+
spx session release [id...]
|
|
84
|
+
|
|
85
|
+
# Archive a session
|
|
86
|
+
spx session archive <session-id>
|
|
75
87
|
|
|
76
88
|
# Show session content
|
|
77
89
|
spx session show <session-id>
|
|
78
90
|
|
|
91
|
+
# Remove old todo sessions (keeps 5 by default)
|
|
92
|
+
spx session prune [--keep <n>] [--dry-run]
|
|
93
|
+
|
|
79
94
|
# Delete a session
|
|
80
95
|
spx session delete <session-id>
|
|
81
96
|
```
|
|
@@ -86,7 +101,7 @@ See [Session Recipes](docs/how-to/session/common-tasks.md) for detailed usage pa
|
|
|
86
101
|
|
|
87
102
|
### Spec Management (deprecated)
|
|
88
103
|
|
|
89
|
-
The `spx spec` and `spx spx` CLI domains are **deprecated**. Spec tree management has moved to the **spec-tree** Claude Code plugin, available at [`outcomeeng/
|
|
104
|
+
The `spx spec` and `spx spx` CLI domains are **deprecated**. Spec tree management has moved to the **spec-tree** Claude Code plugin, available at [`outcomeeng/plugins`](https://github.com/outcomeeng/plugins). The plugin provides skills for understanding, authoring, decomposing, contextualizing, testing, refactoring, and aligning specification trees.
|
|
90
105
|
|
|
91
106
|
## Development
|
|
92
107
|
|
|
@@ -105,50 +120,61 @@ pnpm link --global # Optional: makes 'spx' available in your shell
|
|
|
105
120
|
```bash
|
|
106
121
|
pnpm run build # Build with tsup
|
|
107
122
|
pnpm run dev # Build in watch mode
|
|
108
|
-
pnpm test #
|
|
123
|
+
pnpm test # Build, then run all tests
|
|
109
124
|
pnpm run test:watch # Run tests in watch mode
|
|
110
125
|
pnpm run test:unit # Unit tests only
|
|
111
|
-
pnpm run test:e2e #
|
|
126
|
+
pnpm run test:e2e # Build, then run end-to-end tests
|
|
112
127
|
pnpm run test:coverage # Tests with coverage
|
|
113
128
|
```
|
|
114
129
|
|
|
115
130
|
### Validation (Required Before Commits)
|
|
116
131
|
|
|
117
132
|
```bash
|
|
118
|
-
pnpm run validate
|
|
119
|
-
pnpm run
|
|
120
|
-
pnpm run lint
|
|
121
|
-
pnpm run
|
|
122
|
-
pnpm run
|
|
123
|
-
pnpm run
|
|
133
|
+
pnpm run validate # Source CLI: full validation pipeline
|
|
134
|
+
pnpm run validate:production # Source CLI: production scope only
|
|
135
|
+
pnpm run lint # Source CLI: ESLint only
|
|
136
|
+
pnpm run lint:fix # Source CLI: ESLint with auto-fix
|
|
137
|
+
pnpm run typecheck # Source CLI: TypeScript only
|
|
138
|
+
pnpm run circular # Source CLI: circular dependency detection
|
|
139
|
+
pnpm run knip # Source CLI: unused code detection
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The development validation scripts run `tsx src/cli.ts`, so they validate the current source tree. The packaged executable at `bin/spx.js` requires `dist/cli.js`; run `pnpm run build` before invoking it directly or through a global link.
|
|
143
|
+
|
|
144
|
+
### Publish Validation
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
pnpm run publish:check # Source validation, build, tests, packaged validation
|
|
148
|
+
pnpm run validate:published # Packaged executable validation; requires dist/cli.js
|
|
124
149
|
```
|
|
125
150
|
|
|
126
|
-
|
|
151
|
+
`pnpm run publish:check` is the required pre-publish gate. It runs source validation, builds `dist/`, runs the test suite, and then runs `node bin/spx.js validation all --scope production` against the built executable.
|
|
127
152
|
|
|
128
153
|
## CI/CD
|
|
129
154
|
|
|
130
155
|
The project uses GitHub Actions for continuous integration and publishing:
|
|
131
156
|
|
|
132
|
-
-
|
|
133
|
-
-
|
|
134
|
-
-
|
|
157
|
+
- `ci.yml` — Runs validate, test, and build on Node 22 and 24 for every push to `main` and every pull request. Includes dependency review to block PRs introducing vulnerable dependencies.
|
|
158
|
+
- `publish.yml` — Triggered by `v*` tags. Uses OIDC Trusted Publishing (no stored npm tokens) with Sigstore provenance attestation. Requires manual approval via the `npm-publish` GitHub Environment.
|
|
159
|
+
- `scorecard.yml` — Weekly OpenSSF Scorecard assessment, results published to the GitHub Security tab.
|
|
135
160
|
|
|
136
161
|
### Publishing a Release
|
|
137
162
|
|
|
138
|
-
1.
|
|
139
|
-
2.
|
|
140
|
-
3.
|
|
141
|
-
4.
|
|
142
|
-
5.
|
|
163
|
+
1. Run `pnpm run publish:check`
|
|
164
|
+
2. Bump the version in `package.json`
|
|
165
|
+
3. Commit and tag: `git tag vX.Y.Z`
|
|
166
|
+
4. Push: `git push origin main && git push origin vX.Y.Z`
|
|
167
|
+
5. Approve the deployment in the GitHub Actions `npm-publish` environment
|
|
168
|
+
6. Verify provenance with `npm audit signatures`
|
|
143
169
|
|
|
144
170
|
## Technical Stack
|
|
145
171
|
|
|
146
|
-
-
|
|
147
|
-
-
|
|
148
|
-
-
|
|
149
|
-
-
|
|
150
|
-
-
|
|
151
|
-
-
|
|
172
|
+
- TypeScript — type-safe implementation (ESM)
|
|
173
|
+
- Commander.js — CLI framework
|
|
174
|
+
- Vitest — testing framework
|
|
175
|
+
- tsup — build tool (esbuild-based)
|
|
176
|
+
- ESLint 9 — linting with flat config
|
|
177
|
+
- GitHub Actions — CI/CD with OIDC Trusted Publishing
|
|
152
178
|
|
|
153
179
|
## Architecture
|
|
154
180
|
|
|
@@ -156,7 +182,8 @@ The project uses GitHub Actions for continuous integration and publishing:
|
|
|
156
182
|
src/
|
|
157
183
|
├── commands/ # CLI command implementations
|
|
158
184
|
│ ├── session/ # spx session subcommands
|
|
159
|
-
│
|
|
185
|
+
│ ├── validation/ # spx validation subcommands
|
|
186
|
+
│ └── spec/ # spx spec subcommands (deprecated)
|
|
160
187
|
├── domains/ # Domain routers
|
|
161
188
|
├── validation/ # Lint, typecheck, circular dep logic
|
|
162
189
|
├── session/ # Session lifecycle and storage
|
package/bin/spx.js
CHANGED
|
@@ -1,30 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// CLI entry point
|
|
4
|
-
// Use tsx for development when dist/cli.js doesn't exist
|
|
5
4
|
import { existsSync } from "node:fs";
|
|
6
5
|
import { dirname, join } from "node:path";
|
|
7
|
-
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
|
+
|
|
8
|
+
const BUILD_COMMAND = "pnpm run build";
|
|
9
|
+
const BUILT_CLI_FILENAME = "cli.js";
|
|
10
|
+
const DIST_DIRECTORY = "dist";
|
|
8
11
|
|
|
9
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
13
|
const __dirname = dirname(__filename);
|
|
11
|
-
const distPath = join(__dirname, "
|
|
14
|
+
const distPath = join(__dirname, "..", DIST_DIRECTORY, BUILT_CLI_FILENAME);
|
|
15
|
+
|
|
16
|
+
if (!existsSync(distPath)) {
|
|
17
|
+
console.error(`Built CLI not found at ${distPath}`);
|
|
18
|
+
console.error(`Run "${BUILD_COMMAND}" before invoking the packaged spx executable.`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
12
21
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
process.exit(1);
|
|
19
|
-
}
|
|
20
|
-
} else {
|
|
21
|
-
// Development mode: use tsx to run source directly
|
|
22
|
-
try {
|
|
23
|
-
await import("tsx/esm");
|
|
24
|
-
await import("../src/cli.ts");
|
|
25
|
-
} catch (err) {
|
|
26
|
-
console.error("tsx not available and dist/cli.js not found:", err);
|
|
27
|
-
console.error("Run \"pnpm run build\" to build the CLI");
|
|
28
|
-
process.exit(1);
|
|
29
|
-
}
|
|
22
|
+
try {
|
|
23
|
+
await import(pathToFileURL(distPath).href);
|
|
24
|
+
} catch (err) {
|
|
25
|
+
console.error("Failed to load built CLI:", err);
|
|
26
|
+
process.exit(1);
|
|
30
27
|
}
|