sdtk-ops-kit 0.2.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.
Files changed (51) hide show
  1. package/README.md +146 -0
  2. package/assets/manifest/toolkit-bundle.manifest.json +187 -0
  3. package/assets/manifest/toolkit-bundle.sha256.txt +36 -0
  4. package/assets/toolkit/toolkit/AGENTS.md +65 -0
  5. package/assets/toolkit/toolkit/SDTKOPS_TOOLKIT.md +166 -0
  6. package/assets/toolkit/toolkit/install.ps1 +138 -0
  7. package/assets/toolkit/toolkit/scripts/install-claude-skills.ps1 +81 -0
  8. package/assets/toolkit/toolkit/scripts/install-codex-skills.ps1 +127 -0
  9. package/assets/toolkit/toolkit/scripts/uninstall-claude-skills.ps1 +65 -0
  10. package/assets/toolkit/toolkit/scripts/uninstall-codex-skills.ps1 +53 -0
  11. package/assets/toolkit/toolkit/sdtk-spec.config.json +6 -0
  12. package/assets/toolkit/toolkit/sdtk-spec.config.profiles.example.json +12 -0
  13. package/assets/toolkit/toolkit/skills/ops-backup/SKILL.md +93 -0
  14. package/assets/toolkit/toolkit/skills/ops-backup/references/backup-script-patterns.md +108 -0
  15. package/assets/toolkit/toolkit/skills/ops-ci-cd/SKILL.md +88 -0
  16. package/assets/toolkit/toolkit/skills/ops-ci-cd/references/pipeline-examples.md +113 -0
  17. package/assets/toolkit/toolkit/skills/ops-compliance/SKILL.md +105 -0
  18. package/assets/toolkit/toolkit/skills/ops-container/SKILL.md +95 -0
  19. package/assets/toolkit/toolkit/skills/ops-container/references/k8s-manifest-patterns.md +116 -0
  20. package/assets/toolkit/toolkit/skills/ops-cost/SKILL.md +88 -0
  21. package/assets/toolkit/toolkit/skills/ops-debug/SKILL.md +311 -0
  22. package/assets/toolkit/toolkit/skills/ops-debug/references/root-cause-tracing.md +138 -0
  23. package/assets/toolkit/toolkit/skills/ops-deploy/SKILL.md +102 -0
  24. package/assets/toolkit/toolkit/skills/ops-discover/SKILL.md +102 -0
  25. package/assets/toolkit/toolkit/skills/ops-incident/SKILL.md +113 -0
  26. package/assets/toolkit/toolkit/skills/ops-incident/references/communication-templates.md +34 -0
  27. package/assets/toolkit/toolkit/skills/ops-incident/references/postmortem-template.md +69 -0
  28. package/assets/toolkit/toolkit/skills/ops-incident/references/runbook-template.md +69 -0
  29. package/assets/toolkit/toolkit/skills/ops-infra-plan/SKILL.md +123 -0
  30. package/assets/toolkit/toolkit/skills/ops-infra-plan/references/iac-patterns.md +141 -0
  31. package/assets/toolkit/toolkit/skills/ops-monitor/SKILL.md +110 -0
  32. package/assets/toolkit/toolkit/skills/ops-monitor/references/alert-rules.md +80 -0
  33. package/assets/toolkit/toolkit/skills/ops-monitor/references/slo-templates.md +83 -0
  34. package/assets/toolkit/toolkit/skills/ops-parallel/SKILL.md +177 -0
  35. package/assets/toolkit/toolkit/skills/ops-plan/SKILL.md +169 -0
  36. package/assets/toolkit/toolkit/skills/ops-security-infra/SKILL.md +126 -0
  37. package/assets/toolkit/toolkit/skills/ops-security-infra/references/cicd-security-pipeline.md +55 -0
  38. package/assets/toolkit/toolkit/skills/ops-security-infra/references/security-headers.md +24 -0
  39. package/assets/toolkit/toolkit/skills/ops-verify/SKILL.md +180 -0
  40. package/bin/sdtk-ops.js +14 -0
  41. package/package.json +46 -0
  42. package/src/commands/generate.js +12 -0
  43. package/src/commands/help.js +53 -0
  44. package/src/commands/init.js +86 -0
  45. package/src/commands/runtime.js +201 -0
  46. package/src/index.js +65 -0
  47. package/src/lib/args.js +107 -0
  48. package/src/lib/errors.js +41 -0
  49. package/src/lib/powershell.js +65 -0
  50. package/src/lib/scope.js +58 -0
  51. package/src/lib/toolkit-payload.js +123 -0
@@ -0,0 +1,24 @@
1
+ <!-- Based on agency-agents by AgentLand Contributors (MIT License, 2025). Adapted for SDTK-OPS. -->
2
+
3
+ # Security Headers
4
+
5
+ ```nginx
6
+ server {
7
+ add_header X-Content-Type-Options "nosniff" always;
8
+ add_header X-Frame-Options "DENY" always;
9
+ add_header X-XSS-Protection "1; mode=block" always;
10
+ add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
11
+ add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self';" always;
12
+ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
13
+ add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always;
14
+
15
+ server_tokens off;
16
+ }
17
+ ```
18
+
19
+ ## Pattern Notes
20
+
21
+ - tune CSP to the actual application surface before enforcing it
22
+ - keep headers consistent across edge and app-serving paths
23
+ - remove unnecessary server disclosure where the platform permits it
24
+
@@ -0,0 +1,180 @@
1
+ <!-- Based on superpowers by Jesse Vincent (MIT License, 2025). Adapted for SDTK-OPS. -->
2
+ ---
3
+ name: ops-verify
4
+ description: Verification before completion. Use before claiming any infrastructure change, deployment, or operational task is done -- run verification commands and confirm output, evidence before assertions.
5
+ ---
6
+
7
+ # Ops Verify
8
+
9
+ ## Overview
10
+
11
+ Claiming work is complete without verification is dishonesty, not efficiency.
12
+
13
+ **Core principle:** Evidence before claims, always.
14
+
15
+ **Violating the letter of this rule is violating the spirit of this rule.**
16
+
17
+ ## The Iron Law
18
+
19
+ ```
20
+ NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE
21
+ ```
22
+
23
+ If you have not run the verification command in this message, you cannot claim it passes.
24
+
25
+ ## The Gate Function
26
+
27
+ ```
28
+ BEFORE claiming any status or expressing satisfaction:
29
+
30
+ 1. IDENTIFY: What command proves this claim?
31
+ 2. RUN: Execute the FULL command (fresh, complete)
32
+ 3. READ: Full output, check exit code, count failures
33
+ 4. VERIFY: Does output confirm the claim?
34
+ - If NO: State actual status with evidence
35
+ - If YES: State claim WITH evidence
36
+ 5. ONLY THEN: Make the claim
37
+
38
+ Skip any step = lying, not verifying
39
+ ```
40
+
41
+ ## Common Failures
42
+
43
+ | Claim | Requires | Not Sufficient |
44
+ |-------|----------|----------------|
45
+ | Tests pass | Test command output: 0 failures | Previous run, "should pass" |
46
+ | Linter clean | Linter output: 0 errors | Partial check, extrapolation |
47
+ | Build succeeds | Build command: exit 0 | Linter passing, logs look good |
48
+ | Bug fixed | Test original symptom: passes | Code changed, assumed fixed |
49
+ | Regression test works | Red-green cycle verified | Test passes once |
50
+ | Agent completed | VCS diff shows changes | Agent reports "success" |
51
+ | Requirements met | Line-by-line checklist | Tests passing |
52
+
53
+ ## Common Mistakes
54
+
55
+ | Mistake | Why it fails |
56
+ |---------|--------------|
57
+ | Claim success from expectation instead of output | You report intent, not evidence |
58
+ | Reuse old command output | State may have changed since the earlier run |
59
+ | Verify only one layer of a multi-step change | Hidden failure survives past the claim |
60
+ | Trust a delegated agent without independent checks | Reported completion may not match the actual result |
61
+
62
+ ## Red Flags - STOP
63
+
64
+ - Using "should", "probably", "seems to"
65
+ - Expressing satisfaction before verification ("Great!", "Perfect!", "Done!", etc.)
66
+ - About to commit, push, or close a task without verification
67
+ - Trusting agent success reports
68
+ - Relying on partial verification
69
+ - Thinking "just this once"
70
+ - Tired and wanting work over
71
+ - **ANY wording implying success without having run verification**
72
+
73
+ ## Rationalization Prevention
74
+
75
+ | Excuse | Reality |
76
+ |--------|---------|
77
+ | "Should work now" | RUN the verification |
78
+ | "I'm confident" | Confidence is not evidence |
79
+ | "Just this once" | No exceptions |
80
+ | "Linter passed" | Linter is not compiler |
81
+ | "Agent said success" | Verify independently |
82
+ | "I'm tired" | Exhaustion is not an excuse |
83
+ | "Partial check is enough" | Partial proves nothing |
84
+ | "Different words so rule doesn't apply" | Spirit over letter |
85
+
86
+ ## Key Patterns
87
+
88
+ **Tests:**
89
+ ```
90
+ [Run test command] [See: 34/34 pass] "All tests pass"
91
+ "Should pass now" / "Looks correct"
92
+ ```
93
+
94
+ **Regression tests (TDD Red-Green):**
95
+ ```
96
+ Write -> Run (pass) -> Revert fix -> Run (MUST FAIL) -> Restore -> Run (pass)
97
+ "I've written a regression test" (without red-green verification)
98
+ ```
99
+
100
+ **Build:**
101
+ ```
102
+ [Run build] [See: exit 0] "Build passes"
103
+ "Linter passed" (linter does not check compilation)
104
+ ```
105
+
106
+ **Requirements:**
107
+ ```
108
+ Re-read plan -> Create checklist -> Verify each -> Report gaps or completion
109
+ "Tests pass, phase complete"
110
+ ```
111
+
112
+ **Agent delegation:**
113
+ ```
114
+ Agent reports success -> Check VCS diff -> Verify changes -> Report actual state
115
+ Trust agent report
116
+ ```
117
+
118
+ ## Infrastructure Verification Patterns
119
+
120
+ **Health check:**
121
+ ```
122
+ [Run: curl -s https://service.example/health]
123
+ [See: {"status":"healthy"}]
124
+ "Service healthy"
125
+ ```
126
+
127
+ **DNS:**
128
+ ```
129
+ [Run: dig +short api.example.com]
130
+ [See: correct IP or CNAME]
131
+ "DNS propagated"
132
+ ```
133
+
134
+ **Container:**
135
+ ```
136
+ [Run: kubectl get pods -n production]
137
+ [See: Running, Ready 1/1]
138
+ "Pods healthy"
139
+ ```
140
+
141
+ **Cloud resource:**
142
+ ```
143
+ [Run: provider CLI state check]
144
+ [See: active or available]
145
+ "Resource provisioned"
146
+ ```
147
+
148
+ ## Why This Matters
149
+
150
+ From repeated operational failures:
151
+ - the user stops trusting status claims that are not backed by evidence
152
+ - undefined or unhealthy runtime states can ship into production
153
+ - missing requirements or skipped rollback checks lead to incomplete releases
154
+ - time gets wasted on false completion -> redirect -> rework
155
+ - operational honesty matters as much as implementation honesty
156
+
157
+ ## When To Apply
158
+
159
+ **ALWAYS before:**
160
+ - ANY variation of success or completion claims
161
+ - ANY expression of satisfaction
162
+ - ANY positive statement about operational state
163
+ - Deployment completion
164
+ - Incident closure
165
+ - Moving to the next task
166
+ - Delegating to agents
167
+
168
+ **Rule applies to:**
169
+ - Exact phrases
170
+ - Paraphrases and synonyms
171
+ - Implications of success
172
+ - ANY communication suggesting completion or correctness
173
+
174
+ ## The Bottom Line
175
+
176
+ **No shortcuts for verification.**
177
+
178
+ Run the command. Read the output. THEN claim the result.
179
+
180
+ This is non-negotiable.
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+
3
+ "use strict";
4
+
5
+ const { run } = require("../src/index");
6
+
7
+ run(process.argv.slice(2))
8
+ .then((exitCode) => {
9
+ process.exitCode = Number.isInteger(exitCode) ? exitCode : 0;
10
+ })
11
+ .catch((error) => {
12
+ console.error(`sdtk-ops: ${error.message}`);
13
+ process.exitCode = typeof error.exitCode === "number" ? error.exitCode : 4;
14
+ });
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "sdtk-ops-kit",
3
+ "version": "0.2.0",
4
+ "description": "Skill-driven operations toolkit for deployment, verification, monitoring, incident response, backup, security, compliance, and cost discipline.",
5
+ "bin": {
6
+ "sdtk-ops": "./bin/sdtk-ops.js"
7
+ },
8
+ "main": "src/index.js",
9
+ "type": "commonjs",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/codexsdtk/sdtk-toolkit.git",
13
+ "directory": "products/sdtk-ops/distribution/sdtk-ops-kit"
14
+ },
15
+ "homepage": "https://github.com/codexsdtk/sdtk-toolkit/tree/main/products/sdtk-ops/distribution/sdtk-ops-kit",
16
+ "bugs": {
17
+ "url": "https://github.com/codexsdtk/sdtk-toolkit/issues"
18
+ },
19
+ "files": [
20
+ "bin/",
21
+ "src/",
22
+ "assets/"
23
+ ],
24
+ "scripts": {
25
+ "test": "powershell -ExecutionPolicy Bypass -Command \"$ErrorActionPreference = 'Stop'; Set-Location '..\\..\\..\\..'; python -m unittest -v tests.test_sdtk_ops_cli\"",
26
+ "build:payload": "powershell -ExecutionPolicy Bypass -Command \"$ErrorActionPreference = 'Stop'; & 'scripts/sync-toolkit-assets.ps1'; & 'scripts/build-toolkit-manifest.ps1'\"",
27
+ "verify:payload": "node -e \"require('./src/lib/toolkit-payload').verify()\"",
28
+ "pack:smoke": "powershell -ExecutionPolicy Bypass -File scripts/pack-smoke.ps1",
29
+ "prepublishOnly": "npm run build:payload && npm run verify:payload"
30
+ },
31
+ "engines": {
32
+ "node": ">=18.13.0"
33
+ },
34
+ "keywords": [
35
+ "sdtk-ops",
36
+ "cli",
37
+ "toolkit",
38
+ "operations",
39
+ "claude",
40
+ "codex"
41
+ ],
42
+ "license": "MIT",
43
+ "publishConfig": {
44
+ "access": "public"
45
+ }
46
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ const { ValidationError } = require("../lib/errors");
4
+
5
+ async function cmdGenerate(args) {
6
+ void args;
7
+ throw new ValidationError(
8
+ 'The "generate" command is not part of the supported SDTK-OPS workflow-entry surface. Use "sdtk-ops help" for supported commands and start with the "ops-discover" skill if the correct journey is unclear.'
9
+ );
10
+ }
11
+
12
+ module.exports = { cmdGenerate };
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+
3
+ function cmdHelp() {
4
+ const text = [
5
+ "SDTK-OPS CLI -- internal operations discipline toolkit",
6
+ "",
7
+ "Usage:",
8
+ " sdtk-ops <command> [options]",
9
+ "",
10
+ "Commands:",
11
+ " init Initialize SDTK-OPS files in a project",
12
+ " runtime Manage runtime asset installation (install, uninstall, status)",
13
+ " help Show this help message",
14
+ "",
15
+ "Current supported surface:",
16
+ " Supported now: help, init, runtime install|status|uninstall",
17
+ " Not supported: generate",
18
+ " Package scope: internal_only",
19
+ "",
20
+ "Workflow entry:",
21
+ " After init, choose a journey directly if the goal is clear.",
22
+ " Canonical journeys: deployment, incident, monitoring, backup/recovery.",
23
+ " If the correct path is unclear, start with the ops-discover skill.",
24
+ " Close every journey with ops-verify before declaring work complete.",
25
+ "",
26
+ "Runtime support:",
27
+ " Claude: project + user scope",
28
+ " Codex: user scope only",
29
+ " Gate C0: Codex project scope is rejected",
30
+ "",
31
+ "Global options:",
32
+ " -h, --help Show this help",
33
+ " -v, --version Show version",
34
+ "",
35
+ "Examples:",
36
+ " sdtk-ops --help",
37
+ " sdtk-ops --version",
38
+ " sdtk-ops init --runtime claude --project-path ./my-project",
39
+ " sdtk-ops runtime install --runtime claude --scope project --project-path ./my-project",
40
+ " # Journey routing after init:",
41
+ " # deployment -> ops-plan -> ops-infra-plan -> ops-container -> ops-ci-cd -> ops-deploy -> ops-monitor -> ops-verify",
42
+ " # incident -> ops-incident -> ops-debug -> ops-monitor -> ops-verify",
43
+ " # monitoring -> ops-plan -> ops-monitor -> ops-verify",
44
+ " # recovery -> ops-plan -> ops-backup -> ops-verify",
45
+ " sdtk-ops runtime status --runtime codex",
46
+ " sdtk-ops runtime uninstall --runtime codex --scope user",
47
+ ];
48
+
49
+ console.log(text.join("\n"));
50
+ return 0;
51
+ }
52
+
53
+ module.exports = { cmdHelp };
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+
3
+ const path = require("path");
4
+ const { parseFlags, validateChoice } = require("../lib/args");
5
+ const { verify, resolvePayloadFile } = require("../lib/toolkit-payload");
6
+ const { runScript } = require("../lib/powershell");
7
+ const { ValidationError } = require("../lib/errors");
8
+ const { VALID_SCOPES, defaultScope, isProjectScopeSupported } = require("../lib/scope");
9
+
10
+ const FLAG_DEFS = {
11
+ runtime: { type: "string" },
12
+ "project-path": { type: "string" },
13
+ "runtime-scope": { type: "string" },
14
+ force: { type: "boolean" },
15
+ "skip-skills": { type: "boolean" },
16
+ "skip-runtime-assets": { type: "boolean" },
17
+ verbose: { type: "boolean" },
18
+ };
19
+
20
+ const VALID_RUNTIMES = ["codex", "claude"];
21
+
22
+ async function cmdInit(args) {
23
+ const { flags } = parseFlags(args, FLAG_DEFS);
24
+
25
+ const runtime = flags.runtime || "codex";
26
+ validateChoice(runtime, VALID_RUNTIMES, "runtime");
27
+
28
+ const scope = flags["runtime-scope"] || defaultScope(runtime);
29
+ validateChoice(scope, VALID_SCOPES, "runtime-scope");
30
+ if (scope === "project" && !isProjectScopeSupported(runtime)) {
31
+ throw new ValidationError(
32
+ "Codex does not support project-local skills. Use --runtime-scope user instead."
33
+ );
34
+ }
35
+
36
+ const skipAssets = flags["skip-runtime-assets"] || flags["skip-skills"];
37
+ if (flags["skip-skills"] && !flags["skip-runtime-assets"]) {
38
+ console.warn("Warning: --skip-skills is deprecated. Use --skip-runtime-assets instead.");
39
+ }
40
+
41
+ const projectPath = flags["project-path"] ? path.resolve(flags["project-path"]) : process.cwd();
42
+
43
+ verify();
44
+
45
+ const installScript = resolvePayloadFile("toolkit/install.ps1");
46
+ const params = {
47
+ ProjectPath: projectPath,
48
+ Runtime: runtime,
49
+ Scope: scope,
50
+ };
51
+ if (flags.force) {
52
+ params.Force = true;
53
+ }
54
+ if (skipAssets) {
55
+ params.SkipRuntimeAssets = true;
56
+ }
57
+ if (!flags.verbose) {
58
+ params.Quiet = true;
59
+ }
60
+
61
+ console.log("Initializing SDTK-OPS workspace...");
62
+ console.log(` Runtime: ${runtime}`);
63
+ console.log(` Scope: ${scope}`);
64
+ console.log(` Project: ${projectPath}`);
65
+ console.log("");
66
+
67
+ const result = await runScript(installScript, params, { silent: !flags.verbose });
68
+ if (result.exitCode !== 0) {
69
+ if (result.stderr) {
70
+ console.error(result.stderr);
71
+ }
72
+ throw new ValidationError(`Initialization failed (exit code ${result.exitCode}).`);
73
+ }
74
+
75
+ console.log("");
76
+ console.log("SDTK-OPS workspace initialized successfully.");
77
+ console.log("");
78
+ console.log("Next steps:");
79
+ console.log(" 1. Review and customize sdtk-spec.config.json for your operations environment.");
80
+ console.log(" 2. Use the installed ops-* skill set for deployment, monitoring, incident, and recovery workflows.");
81
+ return 0;
82
+ }
83
+
84
+ module.exports = {
85
+ cmdInit,
86
+ };
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const { parseFlags, requireFlag, validateChoice } = require("../lib/args");
6
+ const { verify, resolvePayloadFile } = require("../lib/toolkit-payload");
7
+ const { runScript } = require("../lib/powershell");
8
+ const { ValidationError } = require("../lib/errors");
9
+ const {
10
+ VALID_SCOPES,
11
+ defaultScope,
12
+ isProjectScopeSupported,
13
+ managedSkillNames,
14
+ resolveSkillsDir,
15
+ } = require("../lib/scope");
16
+
17
+ const FLAG_DEFS = {
18
+ runtime: { type: "string" },
19
+ scope: { type: "string" },
20
+ "project-path": { type: "string" },
21
+ force: { type: "boolean" },
22
+ all: { type: "boolean" },
23
+ verbose: { type: "boolean" },
24
+ };
25
+
26
+ const VALID_RUNTIMES = ["codex", "claude"];
27
+ const SUBCOMMANDS = ["install", "uninstall", "status"];
28
+
29
+ function validateScopeForRuntime(runtime, scope, label) {
30
+ if (scope === "project" && !isProjectScopeSupported(runtime)) {
31
+ throw new ValidationError(
32
+ `Codex does not support project-local skills. Use --${label} user instead.`
33
+ );
34
+ }
35
+ }
36
+
37
+ async function cmdRuntimeInstall(flags) {
38
+ const runtime = requireFlag(flags, "runtime", "runtime");
39
+ validateChoice(runtime, VALID_RUNTIMES, "runtime");
40
+
41
+ const scope = flags.scope || defaultScope(runtime);
42
+ validateChoice(scope, VALID_SCOPES, "scope");
43
+ validateScopeForRuntime(runtime, scope, "scope");
44
+
45
+ const projectPath = flags["project-path"] ? path.resolve(flags["project-path"]) : process.cwd();
46
+ verify();
47
+
48
+ const scriptName =
49
+ runtime === "claude"
50
+ ? "toolkit/scripts/install-claude-skills.ps1"
51
+ : "toolkit/scripts/install-codex-skills.ps1";
52
+ const script = resolvePayloadFile(scriptName);
53
+ const params = { Scope: scope };
54
+ if (runtime === "claude") {
55
+ params.ProjectPath = projectPath;
56
+ }
57
+ if (flags.force) {
58
+ params.Force = true;
59
+ }
60
+ if (!flags.verbose) {
61
+ params.Quiet = true;
62
+ }
63
+
64
+ console.log(`Installing ${runtime} runtime assets...`);
65
+ console.log(` Runtime: ${runtime}`);
66
+ console.log(` Scope: ${scope}`);
67
+ if (runtime === "claude" && scope === "project") {
68
+ console.log(` Project: ${projectPath}`);
69
+ }
70
+ console.log("");
71
+
72
+ const result = await runScript(script, params, { silent: !flags.verbose });
73
+ if (result.exitCode !== 0) {
74
+ if (result.stderr) {
75
+ console.error(result.stderr);
76
+ }
77
+ throw new ValidationError(`Runtime install failed (exit code ${result.exitCode}).`);
78
+ }
79
+
80
+ console.log("");
81
+ console.log(`${runtime} runtime assets installed successfully.`);
82
+ return 0;
83
+ }
84
+
85
+ async function cmdRuntimeUninstall(flags) {
86
+ const runtime = requireFlag(flags, "runtime", "runtime");
87
+ validateChoice(runtime, VALID_RUNTIMES, "runtime");
88
+
89
+ const scope = flags.scope || defaultScope(runtime);
90
+ validateChoice(scope, VALID_SCOPES, "scope");
91
+ validateScopeForRuntime(runtime, scope, "scope");
92
+
93
+ const projectPath = flags["project-path"] ? path.resolve(flags["project-path"]) : process.cwd();
94
+ verify();
95
+
96
+ const scriptName =
97
+ runtime === "claude"
98
+ ? "toolkit/scripts/uninstall-claude-skills.ps1"
99
+ : "toolkit/scripts/uninstall-codex-skills.ps1";
100
+ const script = resolvePayloadFile(scriptName);
101
+ const params = { All: true };
102
+ if (runtime === "claude") {
103
+ params.Scope = scope;
104
+ params.ProjectPath = projectPath;
105
+ }
106
+ if (!flags.verbose) {
107
+ params.Quiet = true;
108
+ }
109
+
110
+ const result = await runScript(script, params, { silent: !flags.verbose });
111
+ if (result.exitCode !== 0) {
112
+ if (result.stderr) {
113
+ console.error(result.stderr);
114
+ }
115
+ throw new ValidationError(`Runtime uninstall failed (exit code ${result.exitCode}).`);
116
+ }
117
+
118
+ console.log(`Uninstalled ${runtime} runtime assets for scope ${scope}.`);
119
+ return 0;
120
+ }
121
+
122
+ function cmdRuntimeStatus(flags) {
123
+ const runtime = requireFlag(flags, "runtime", "runtime");
124
+ validateChoice(runtime, VALID_RUNTIMES, "runtime");
125
+
126
+ const projectPath = flags["project-path"] ? path.resolve(flags["project-path"]) : process.cwd();
127
+ const scopes = runtime === "claude" ? ["project", "user"] : ["user"];
128
+
129
+ console.log(`Runtime: ${runtime}`);
130
+ console.log("");
131
+
132
+ for (const scope of scopes) {
133
+ const skillsDir = resolveSkillsDir(runtime, scope, projectPath);
134
+ const managed = managedSkillNames(runtime);
135
+ const exists = fs.existsSync(skillsDir);
136
+ let installedNames = [];
137
+
138
+ if (exists) {
139
+ try {
140
+ const entries = fs.readdirSync(skillsDir, { withFileTypes: true });
141
+ installedNames = entries
142
+ .filter((entry) => entry.isDirectory() && managed.includes(entry.name))
143
+ .map((entry) => entry.name)
144
+ .sort();
145
+ } catch {
146
+ installedNames = [];
147
+ }
148
+ }
149
+
150
+ const skillCount = installedNames.length;
151
+ const allInstalled = skillCount === managed.length;
152
+ const hasManagedSkills = skillCount > 0;
153
+ const status = !exists || !hasManagedSkills
154
+ ? "not installed"
155
+ : allInstalled
156
+ ? `installed (${skillCount}/${managed.length} SDTK-OPS skills)`
157
+ : `partial (${skillCount}/${managed.length} SDTK-OPS skills)`;
158
+
159
+ console.log(` Scope: ${scope}`);
160
+ console.log(` Path: ${skillsDir}`);
161
+ console.log(` Status: ${status}`);
162
+ if (exists && hasManagedSkills && skillCount < managed.length) {
163
+ const missing = managed.filter((name) => !installedNames.includes(name));
164
+ console.log(` Missing: ${missing.join(", ")}`);
165
+ }
166
+ console.log("");
167
+ }
168
+
169
+ return 0;
170
+ }
171
+
172
+ async function cmdRuntime(args) {
173
+ const { flags, positional } = parseFlags(args, FLAG_DEFS);
174
+ const subcommand = positional[0];
175
+
176
+ if (!subcommand) {
177
+ throw new ValidationError(
178
+ `Missing subcommand. Usage: sdtk-ops runtime <${SUBCOMMANDS.join("|")}> [options]`
179
+ );
180
+ }
181
+ if (!SUBCOMMANDS.includes(subcommand)) {
182
+ throw new ValidationError(
183
+ `Unknown subcommand: "${subcommand}". Must be one of: ${SUBCOMMANDS.join(", ")}`
184
+ );
185
+ }
186
+
187
+ switch (subcommand) {
188
+ case "install":
189
+ return cmdRuntimeInstall(flags);
190
+ case "uninstall":
191
+ return cmdRuntimeUninstall(flags);
192
+ case "status":
193
+ return cmdRuntimeStatus(flags);
194
+ default:
195
+ throw new ValidationError(`Unsupported runtime subcommand: "${subcommand}".`);
196
+ }
197
+ }
198
+
199
+ module.exports = {
200
+ cmdRuntime,
201
+ };
package/src/index.js ADDED
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+
3
+ const { cmdHelp } = require("./commands/help");
4
+ const { cmdInit } = require("./commands/init");
5
+ const { cmdRuntime } = require("./commands/runtime");
6
+ const { ValidationError } = require("./lib/errors");
7
+
8
+ const COMMANDS = new Set(["help", "version", "init", "runtime"]);
9
+
10
+ function getVersion() {
11
+ const pkg = require("../package.json");
12
+ return pkg.version;
13
+ }
14
+
15
+ function parseCommand(argv) {
16
+ if (!argv || argv.length === 0) {
17
+ return { command: "help", args: [] };
18
+ }
19
+
20
+ const [first, ...rest] = argv;
21
+ if (first === "-h" || first === "--help") {
22
+ return { command: "help", args: [] };
23
+ }
24
+ if (first === "-v" || first === "--version") {
25
+ return { command: "version", args: [] };
26
+ }
27
+
28
+ return { command: first, args: rest };
29
+ }
30
+
31
+ async function run(argv) {
32
+ const { command, args } = parseCommand(argv);
33
+
34
+ if (command === "generate") {
35
+ throw new ValidationError(
36
+ 'The "generate" command is not part of the supported SDTK-OPS workflow-entry surface. Supported commands: help, init, runtime. If the correct journey is unclear, start with the "ops-discover" skill.'
37
+ );
38
+ }
39
+
40
+ if (!COMMANDS.has(command)) {
41
+ throw new ValidationError(
42
+ `Unknown command: "${command}". Run "sdtk-ops --help" for available commands.`
43
+ );
44
+ }
45
+
46
+ switch (command) {
47
+ case "help":
48
+ return cmdHelp();
49
+ case "version":
50
+ console.log(`sdtk-ops-kit ${getVersion()}`);
51
+ return 0;
52
+ case "init":
53
+ return cmdInit(args);
54
+ case "runtime":
55
+ return cmdRuntime(args);
56
+ default:
57
+ throw new ValidationError(`Unsupported command: "${command}".`);
58
+ }
59
+ }
60
+
61
+ module.exports = {
62
+ getVersion,
63
+ parseCommand,
64
+ run,
65
+ };