sdtk-kit 1.3.0 → 1.3.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/README.md +22 -10
- package/bin/sdtk.js +14 -5
- package/package.json +2 -2
- package/scripts/unified-init.test.js +53 -3
- package/src/commands/init.js +20 -9
- package/src/lib/unified-init.js +14 -8
package/README.md
CHANGED
|
@@ -34,22 +34,34 @@ sdtk-spec generate --feature-key MY_FEATURE
|
|
|
34
34
|
each toolkit's own, already-shipped `init` in order:
|
|
35
35
|
|
|
36
36
|
```
|
|
37
|
-
sdtk-spec → sdtk-ops → sdtk-code (with --runtime <r>)
|
|
38
|
-
sdtk-
|
|
37
|
+
sdtk-spec → sdtk-ops → sdtk-code → sdtk-design (with --runtime <r>)
|
|
38
|
+
sdtk-wiki (its own non-runtime init)
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
42
|
sdtk init --runtime claude
|
|
43
43
|
sdtk init --runtime codex --project-path ./my-app
|
|
44
|
+
sdtk init --runtime claude --global # install skills to the user/global home
|
|
44
45
|
sdtk init --runtime claude --keep-going # continue past a failing toolkit
|
|
45
46
|
```
|
|
46
47
|
|
|
47
|
-
Options: `--runtime <claude|codex>` (required), `--runtime-scope <
|
|
48
|
-
`--
|
|
49
|
-
(default is fail-fast — stop
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
`--
|
|
48
|
+
Options: `--runtime <claude|codex>` (required), `--runtime-scope <project|user>`,
|
|
49
|
+
`--global` (shorthand for `--runtime-scope user`), `--project-path <path>`,
|
|
50
|
+
`--force`, `--skip-runtime-assets`, `--keep-going` (default is fail-fast — stop
|
|
51
|
+
at the first failing toolkit), `--verbose`.
|
|
52
|
+
|
|
53
|
+
`--runtime`, `--runtime-scope`, and `--global` apply to the runtime-aware
|
|
54
|
+
toolkits (spec/ops/code **and** sdtk-design), so each places its skills under the
|
|
55
|
+
matching runtime home: `.claude/skills` for claude, `.codex/skills` for codex
|
|
56
|
+
(and `~/.claude/skills` / `~/.codex/skills` for `--global`). `--skip-runtime-assets`
|
|
57
|
+
applies only to spec/ops/code (which own the PowerShell runtime-asset payload).
|
|
58
|
+
`sdtk-wiki` installs no skills and receives only `--project-path`, `--force`,
|
|
59
|
+
and `--verbose`.
|
|
60
|
+
|
|
61
|
+
> Note: claude defaults to **project** scope (`.claude/skills`); codex defaults
|
|
62
|
+
> to **user/global** scope (`~/.codex/skills`), since Codex discovers skills via
|
|
63
|
+
> `CODEX_HOME`. Pass `--runtime-scope project` with codex to get a project-local
|
|
64
|
+
> `.codex/skills` (then launch Codex with `CODEX_HOME=<project>/.codex`).
|
|
53
65
|
|
|
54
66
|
`sdtk init` is a thin orchestrator: it re-implements no init logic, writes no files
|
|
55
67
|
itself, and runs no PowerShell of its own — every side effect happens inside the
|
|
@@ -106,14 +118,14 @@ are the mechanism that puts `sdtk`, `sdtk-spec`, `sdtk-code`, `sdtk-ops`,
|
|
|
106
118
|
- **Major version bumps** in any sub-toolkit require a coordinated `sdtk-kit` major-bump and re-publish.
|
|
107
119
|
- If you need exact version control per toolkit, use standalone packages instead.
|
|
108
120
|
|
|
109
|
-
Current dependency ranges (as of sdtk-kit v1.3.
|
|
121
|
+
Current dependency ranges (as of sdtk-kit v1.3.1):
|
|
110
122
|
|
|
111
123
|
| Package | Version |
|
|
112
124
|
|------------------|---------|
|
|
113
125
|
| sdtk-spec-kit | ^0.4.7 |
|
|
114
126
|
| sdtk-code-kit | ^0.3.0 |
|
|
115
127
|
| sdtk-ops-kit | ^0.2.4 |
|
|
116
|
-
| sdtk-design-kit | ^0.3.
|
|
128
|
+
| sdtk-design-kit | ^0.3.2 |
|
|
117
129
|
| sdtk-wiki-kit | ^0.2.0 |
|
|
118
130
|
|
|
119
131
|
## Updating
|
package/bin/sdtk.js
CHANGED
|
@@ -28,16 +28,25 @@ function helpText() {
|
|
|
28
28
|
" sdtk --version Show versions",
|
|
29
29
|
"",
|
|
30
30
|
"init options:",
|
|
31
|
-
" --runtime <claude|codex> Required. Runtime
|
|
32
|
-
"
|
|
31
|
+
" --runtime <claude|codex> Required. Runtime for the runtime-aware kits",
|
|
32
|
+
" (spec/ops/code and design place skills under",
|
|
33
|
+
" .claude/skills or .codex/skills accordingly).",
|
|
34
|
+
" --runtime-scope <project|user> Optional. project = repo-local skills dir;",
|
|
35
|
+
" user = global home. Default: claude→project,",
|
|
36
|
+
" codex→user (Codex discovers skills via CODEX_HOME).",
|
|
37
|
+
" --global Shorthand for --runtime-scope user (~/.claude or",
|
|
38
|
+
" ~/.codex). Applies to both runtimes.",
|
|
33
39
|
" --project-path <path> Optional. Target project directory.",
|
|
34
40
|
" --force Re-initialise existing assets.",
|
|
35
|
-
" --skip-runtime-assets Skip runtime asset install (
|
|
41
|
+
" --skip-runtime-assets Skip PowerShell runtime asset install (spec/ops/code).",
|
|
36
42
|
" --keep-going Continue past a failing toolkit (default: fail-fast).",
|
|
37
43
|
" --verbose Verbose per-toolkit output.",
|
|
38
44
|
"",
|
|
39
|
-
"Runs: sdtk-spec → sdtk-ops → sdtk-code
|
|
40
|
-
"
|
|
45
|
+
"Runs: sdtk-spec → sdtk-ops → sdtk-code → sdtk-design (all with --runtime)",
|
|
46
|
+
" → sdtk-wiki (its own non-runtime init; installs no skills).",
|
|
47
|
+
"",
|
|
48
|
+
"Note: for a project-local .codex with codex, pass --runtime-scope project and",
|
|
49
|
+
"launch Codex with CODEX_HOME=<project>/.codex (no native .codex auto-discovery).",
|
|
41
50
|
"",
|
|
42
51
|
"Standalone per-toolkit CLIs remain available: sdtk-spec, sdtk-ops, sdtk-code,",
|
|
43
52
|
"sdtk-design, sdtk-wiki.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sdtk-kit",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Install all five SDTK toolkits in one command. Meta-package for sdtk-spec-kit, sdtk-code-kit, sdtk-ops-kit, sdtk-design-kit, and sdtk-wiki-kit.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"bin": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"sdtk-spec-kit": "^0.4.7",
|
|
30
30
|
"sdtk-code-kit": "^0.3.0",
|
|
31
31
|
"sdtk-ops-kit": "^0.2.4",
|
|
32
|
-
"sdtk-design-kit": "^0.3.
|
|
32
|
+
"sdtk-design-kit": "^0.3.2",
|
|
33
33
|
"sdtk-wiki-kit": "^0.2.0"
|
|
34
34
|
},
|
|
35
35
|
"engines": {
|
|
@@ -12,9 +12,14 @@ const {
|
|
|
12
12
|
TOOLKITS,
|
|
13
13
|
ToolkitResolveError,
|
|
14
14
|
} = require("../src/lib/unified-init");
|
|
15
|
+
const { parseFlags, buildOpts } = require("../src/commands/init");
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
// spec/ops/code own the PowerShell runtime-asset payload (install.ps1) and so
|
|
18
|
+
// also accept --skip-runtime-assets. sdtk-design is runtime-aware (places the
|
|
19
|
+
// design-prototype skill under .claude/.codex) but does NOT take that flag.
|
|
20
|
+
const ASSET_KITS = ["sdtk-spec", "sdtk-ops", "sdtk-code"];
|
|
21
|
+
const RUNTIME_KITS = ["sdtk-spec", "sdtk-ops", "sdtk-code", "sdtk-design"];
|
|
22
|
+
const NON_RUNTIME_KITS = ["sdtk-wiki"];
|
|
18
23
|
|
|
19
24
|
// Build an injected deps object with a recording spawn spy.
|
|
20
25
|
// `failures` maps toolkit name → exit code to return (default 0).
|
|
@@ -95,7 +100,7 @@ test("T3 forwards shared flags to runtime kits; only subset to design/wiki", ()
|
|
|
95
100
|
};
|
|
96
101
|
runUnifiedInit(opts, h.deps);
|
|
97
102
|
|
|
98
|
-
for (const kit of
|
|
103
|
+
for (const kit of ASSET_KITS) {
|
|
99
104
|
const argv = argvFor(h.spawnCalls, kit);
|
|
100
105
|
assert.deepStrictEqual(
|
|
101
106
|
argv,
|
|
@@ -114,6 +119,27 @@ test("T3 forwards shared flags to runtime kits; only subset to design/wiki", ()
|
|
|
114
119
|
`${kit} full forward`
|
|
115
120
|
);
|
|
116
121
|
}
|
|
122
|
+
// design is runtime-aware (gets --runtime/--runtime-scope) but owns no
|
|
123
|
+
// PowerShell payload, so it must NOT receive --skip-runtime-assets.
|
|
124
|
+
{
|
|
125
|
+
const argv = argvFor(h.spawnCalls, "sdtk-design");
|
|
126
|
+
assert.deepStrictEqual(
|
|
127
|
+
argv,
|
|
128
|
+
[
|
|
129
|
+
"init",
|
|
130
|
+
"--runtime",
|
|
131
|
+
"claude",
|
|
132
|
+
"--runtime-scope",
|
|
133
|
+
"user",
|
|
134
|
+
"--project-path",
|
|
135
|
+
"/tmp/proj",
|
|
136
|
+
"--force",
|
|
137
|
+
"--verbose",
|
|
138
|
+
],
|
|
139
|
+
"sdtk-design runtime-aware forward (no --skip-runtime-assets)"
|
|
140
|
+
);
|
|
141
|
+
assert.ok(!argv.includes("--skip-runtime-assets"), "design must not get --skip-runtime-assets");
|
|
142
|
+
}
|
|
117
143
|
for (const kit of NON_RUNTIME_KITS) {
|
|
118
144
|
const argv = argvFor(h.spawnCalls, kit);
|
|
119
145
|
assert.deepStrictEqual(
|
|
@@ -223,6 +249,30 @@ test("T10 orchestrator uses only injected deps (no real host access)", () => {
|
|
|
223
249
|
assert.deepStrictEqual(a, b);
|
|
224
250
|
});
|
|
225
251
|
|
|
252
|
+
// ── T11 — --global shorthand maps to runtime-scope user ─────────────────────
|
|
253
|
+
test("T11 --global parses and maps to runtimeScope=user", () => {
|
|
254
|
+
const flags = parseFlags(["--runtime", "claude", "--global"]);
|
|
255
|
+
assert.strictEqual(flags.global, true);
|
|
256
|
+
const opts = buildOpts(flags);
|
|
257
|
+
assert.strictEqual(opts.runtimeScope, "user");
|
|
258
|
+
});
|
|
259
|
+
test("T11b explicit --runtime-scope wins over --global", () => {
|
|
260
|
+
const opts = buildOpts(parseFlags(["--runtime", "codex", "--global", "--runtime-scope", "project"]));
|
|
261
|
+
assert.strictEqual(opts.runtimeScope, "project");
|
|
262
|
+
});
|
|
263
|
+
test("T11c no scope flag leaves runtimeScope undefined (kits apply their default)", () => {
|
|
264
|
+
const opts = buildOpts(parseFlags(["--runtime", "codex"]));
|
|
265
|
+
assert.strictEqual(opts.runtimeScope, undefined);
|
|
266
|
+
});
|
|
267
|
+
test("T11d --global forwards --runtime-scope user to design (runtime-aware)", () => {
|
|
268
|
+
const h = makeDeps();
|
|
269
|
+
runUnifiedInit(buildOpts(parseFlags(["--runtime", "claude", "--global"])), h.deps);
|
|
270
|
+
assert.deepStrictEqual(
|
|
271
|
+
argvFor(h.spawnCalls, "sdtk-design"),
|
|
272
|
+
["init", "--runtime", "claude", "--runtime-scope", "user"]
|
|
273
|
+
);
|
|
274
|
+
});
|
|
275
|
+
|
|
226
276
|
// ── runner ──────────────────────────────────────────────────────────────────
|
|
227
277
|
let passed = 0;
|
|
228
278
|
let failed = 0;
|
package/src/commands/init.js
CHANGED
|
@@ -16,6 +16,7 @@ const {
|
|
|
16
16
|
const FLAG_DEFS = Object.freeze({
|
|
17
17
|
runtime: "string",
|
|
18
18
|
"runtime-scope": "string",
|
|
19
|
+
global: "boolean",
|
|
19
20
|
"project-path": "string",
|
|
20
21
|
force: "boolean",
|
|
21
22
|
"skip-runtime-assets": "boolean",
|
|
@@ -57,6 +58,23 @@ function parseFlags(args) {
|
|
|
57
58
|
return flags;
|
|
58
59
|
}
|
|
59
60
|
|
|
61
|
+
// Pure flags → orchestrator opts mapping (exported for unit testing).
|
|
62
|
+
// --global is a shorthand for --runtime-scope user (installs skills under the
|
|
63
|
+
// user/global runtime home: ~/.claude/skills or ~/.codex/skills). An explicit
|
|
64
|
+
// --runtime-scope wins if both are supplied.
|
|
65
|
+
function buildOpts(flags) {
|
|
66
|
+
const runtimeScope = flags["runtime-scope"] || (flags.global ? "user" : undefined);
|
|
67
|
+
return {
|
|
68
|
+
runtime: flags.runtime,
|
|
69
|
+
runtimeScope,
|
|
70
|
+
projectPath: flags["project-path"],
|
|
71
|
+
force: Boolean(flags.force),
|
|
72
|
+
skipRuntimeAssets: Boolean(flags["skip-runtime-assets"]),
|
|
73
|
+
keepGoing: Boolean(flags["keep-going"]),
|
|
74
|
+
verbose: Boolean(flags.verbose),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
60
78
|
function cmdInit(args) {
|
|
61
79
|
let flags;
|
|
62
80
|
try {
|
|
@@ -66,15 +84,7 @@ function cmdInit(args) {
|
|
|
66
84
|
return 2;
|
|
67
85
|
}
|
|
68
86
|
|
|
69
|
-
const opts =
|
|
70
|
-
runtime: flags.runtime,
|
|
71
|
-
runtimeScope: flags["runtime-scope"],
|
|
72
|
-
projectPath: flags["project-path"],
|
|
73
|
-
force: Boolean(flags.force),
|
|
74
|
-
skipRuntimeAssets: Boolean(flags["skip-runtime-assets"]),
|
|
75
|
-
keepGoing: Boolean(flags["keep-going"]),
|
|
76
|
-
verbose: Boolean(flags.verbose),
|
|
77
|
-
};
|
|
87
|
+
const opts = buildOpts(flags);
|
|
78
88
|
|
|
79
89
|
const deps = {
|
|
80
90
|
spawn(binPath, argv) {
|
|
@@ -92,4 +102,5 @@ function cmdInit(args) {
|
|
|
92
102
|
module.exports = {
|
|
93
103
|
cmdInit,
|
|
94
104
|
parseFlags,
|
|
105
|
+
buildOpts,
|
|
95
106
|
};
|
package/src/lib/unified-init.js
CHANGED
|
@@ -18,14 +18,20 @@ const VALID_RUNTIMES = Object.freeze(["claude", "codex"]);
|
|
|
18
18
|
// Ordered target registry. `binName` is the bin key in each kit's package.json
|
|
19
19
|
// (resolved through its `bin` map at runtime, so a kit renaming its bin file
|
|
20
20
|
// across a minor version does not break us — see R1 in the implementation plan).
|
|
21
|
-
//
|
|
22
|
-
//
|
|
21
|
+
//
|
|
22
|
+
// `acceptsRuntime` toolkits receive --runtime (+ --runtime-scope) so they place
|
|
23
|
+
// their skills under the correct runtime home (.claude vs .codex). Of those,
|
|
24
|
+
// only `installsRuntimeAssets` toolkits (spec/ops/code, which run install.ps1)
|
|
25
|
+
// also accept --skip-runtime-assets. sdtk-design is runtime-aware (it installs
|
|
26
|
+
// the design-prototype skill into the matching skills dir) but does not own the
|
|
27
|
+
// PowerShell runtime-asset payload. sdtk-wiki is not runtime-aware (it installs
|
|
28
|
+
// no skills) and receives only --project-path / --force / --verbose.
|
|
23
29
|
const TOOLKITS = Object.freeze([
|
|
24
|
-
{ name: "sdtk-spec", kitPkg: "sdtk-spec-kit", binName: "sdtk-spec", acceptsRuntime: true },
|
|
25
|
-
{ name: "sdtk-ops", kitPkg: "sdtk-ops-kit", binName: "sdtk-ops", acceptsRuntime: true },
|
|
26
|
-
{ name: "sdtk-code", kitPkg: "sdtk-code-kit", binName: "sdtk-code", acceptsRuntime: true },
|
|
27
|
-
{ name: "sdtk-design", kitPkg: "sdtk-design-kit", binName: "sdtk-design", acceptsRuntime: false },
|
|
28
|
-
{ name: "sdtk-wiki", kitPkg: "sdtk-wiki-kit", binName: "sdtk-wiki", acceptsRuntime: false },
|
|
30
|
+
{ name: "sdtk-spec", kitPkg: "sdtk-spec-kit", binName: "sdtk-spec", acceptsRuntime: true, installsRuntimeAssets: true },
|
|
31
|
+
{ name: "sdtk-ops", kitPkg: "sdtk-ops-kit", binName: "sdtk-ops", acceptsRuntime: true, installsRuntimeAssets: true },
|
|
32
|
+
{ name: "sdtk-code", kitPkg: "sdtk-code-kit", binName: "sdtk-code", acceptsRuntime: true, installsRuntimeAssets: true },
|
|
33
|
+
{ name: "sdtk-design", kitPkg: "sdtk-design-kit", binName: "sdtk-design", acceptsRuntime: true, installsRuntimeAssets: false },
|
|
34
|
+
{ name: "sdtk-wiki", kitPkg: "sdtk-wiki-kit", binName: "sdtk-wiki", acceptsRuntime: false, installsRuntimeAssets: false },
|
|
29
35
|
]);
|
|
30
36
|
|
|
31
37
|
// Mirrors sdtk-{spec,ops,code} scope.js: claude defaults to project, codex to user.
|
|
@@ -107,7 +113,7 @@ function buildInitArgs(toolkit, opts) {
|
|
|
107
113
|
if (opts.force) {
|
|
108
114
|
args.push("--force");
|
|
109
115
|
}
|
|
110
|
-
if (toolkit.
|
|
116
|
+
if (toolkit.installsRuntimeAssets && opts.skipRuntimeAssets) {
|
|
111
117
|
args.push("--skip-runtime-assets");
|
|
112
118
|
}
|
|
113
119
|
if (opts.verbose) {
|