sdtk-kit 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 +131 -0
- package/assets/manifest/toolkit-bundle.manifest.json +303 -0
- package/assets/manifest/toolkit-bundle.sha256.txt +59 -0
- package/assets/toolkit/toolkit/AGENTS.md +103 -0
- package/assets/toolkit/toolkit/install.ps1 +155 -0
- package/assets/toolkit/toolkit/runtimes/claude/CLAUDE_TEMPLATE.md +32 -0
- package/assets/toolkit/toolkit/runtimes/codex/CODEX_TEMPLATE.md +32 -0
- package/assets/toolkit/toolkit/scripts/init-feature.ps1 +253 -0
- package/assets/toolkit/toolkit/scripts/install-codex-skills.ps1 +181 -0
- package/assets/toolkit/toolkit/scripts/uninstall-codex-skills.ps1 +116 -0
- package/assets/toolkit/toolkit/sdtk.config.json +28 -0
- package/assets/toolkit/toolkit/sdtk.config.profiles.example.json +50 -0
- package/assets/toolkit/toolkit/skills/sdtk-api-design-spec/SKILL.md +78 -0
- package/assets/toolkit/toolkit/skills/sdtk-api-design-spec/references/API_DESIGN_CREATION_RULES.md +212 -0
- package/assets/toolkit/toolkit/skills/sdtk-api-design-spec/references/FLOWCHART_CREATION_RULES.md +397 -0
- package/assets/toolkit/toolkit/skills/sdtk-api-design-spec/scripts/generate_api_design_detail.py +565 -0
- package/assets/toolkit/toolkit/skills/sdtk-api-doc/SKILL.md +36 -0
- package/assets/toolkit/toolkit/skills/sdtk-api-doc/references/FLOWCHART_CREATION_RULES.md +397 -0
- package/assets/toolkit/toolkit/skills/sdtk-arch/SKILL.md +43 -0
- package/assets/toolkit/toolkit/skills/sdtk-arch/references/API_DESIGN_CREATION_RULES.md +212 -0
- package/assets/toolkit/toolkit/skills/sdtk-arch/references/FLOWCHART_CREATION_RULES.md +397 -0
- package/assets/toolkit/toolkit/skills/sdtk-arch/references/FLOW_ACTION_SPEC_CREATION_RULES.md +136 -0
- package/assets/toolkit/toolkit/skills/sdtk-ba/SKILL.md +24 -0
- package/assets/toolkit/toolkit/skills/sdtk-design-layout/SKILL.md +21 -0
- package/assets/toolkit/toolkit/skills/sdtk-dev/SKILL.md +20 -0
- package/assets/toolkit/toolkit/skills/sdtk-dev-backend/SKILL.md +17 -0
- package/assets/toolkit/toolkit/skills/sdtk-dev-frontend/SKILL.md +15 -0
- package/assets/toolkit/toolkit/skills/sdtk-orchestrator/SKILL.md +44 -0
- package/assets/toolkit/toolkit/skills/sdtk-pm/SKILL.md +26 -0
- package/assets/toolkit/toolkit/skills/sdtk-qa/SKILL.md +22 -0
- package/assets/toolkit/toolkit/skills/sdtk-screen-design-spec/SKILL.md +59 -0
- package/assets/toolkit/toolkit/skills/sdtk-screen-design-spec/references/FLOW_ACTION_SPEC_CREATION_RULES.md +136 -0
- package/assets/toolkit/toolkit/skills/sdtk-screen-design-spec/references/excel-image-export.md +51 -0
- package/assets/toolkit/toolkit/skills/sdtk-screen-design-spec/references/figma-mcp.md +54 -0
- package/assets/toolkit/toolkit/skills/sdtk-screen-design-spec/references/numbering-rules.md +76 -0
- package/assets/toolkit/toolkit/skills/sdtk-screen-design-spec/scripts/renumber_flow_action_spec_global.py +136 -0
- package/assets/toolkit/toolkit/skills/sdtk-screen-design-spec/scripts/validate_flow_action_spec_numbering.py +249 -0
- package/assets/toolkit/toolkit/skills/sdtk-test-case-spec/SKILL.md +65 -0
- package/assets/toolkit/toolkit/skills/sdtk-test-case-spec/references/TEST_CASE_CREATION_RULES.md +129 -0
- package/assets/toolkit/toolkit/skills/sdtk-test-case-spec/scripts/validate_test_case_spec.py +97 -0
- package/assets/toolkit/toolkit/templates/QUALITY_CHECKLIST.md +124 -0
- package/assets/toolkit/toolkit/templates/README.md +56 -0
- package/assets/toolkit/toolkit/templates/SHARED_PLANNING.md +80 -0
- package/assets/toolkit/toolkit/templates/docs/api/API_DESIGN_CREATION_RULES.md +212 -0
- package/assets/toolkit/toolkit/templates/docs/api/API_DESIGN_DETAIL_TEMPLATE.md +62 -0
- package/assets/toolkit/toolkit/templates/docs/api/API_ENDPOINTS_TEMPLATE.md +229 -0
- package/assets/toolkit/toolkit/templates/docs/api/FEATURE_API_TEMPLATE.yaml +20 -0
- package/assets/toolkit/toolkit/templates/docs/api/FLOWCHART_CREATION_RULES.md +397 -0
- package/assets/toolkit/toolkit/templates/docs/api/feature_api_flow_list_TEMPLATE.txt +12 -0
- package/assets/toolkit/toolkit/templates/docs/architecture/ARCH_DESIGN_TEMPLATE.md +109 -0
- package/assets/toolkit/toolkit/templates/docs/database/DATABASE_SPEC_TEMPLATE.md +175 -0
- package/assets/toolkit/toolkit/templates/docs/design/DESIGN_LAYOUT_TEMPLATE.md +49 -0
- package/assets/toolkit/toolkit/templates/docs/dev/FEATURE_IMPL_PLAN_TEMPLATE.md +73 -0
- package/assets/toolkit/toolkit/templates/docs/product/BACKLOG_TEMPLATE.md +50 -0
- package/assets/toolkit/toolkit/templates/docs/product/PRD_TEMPLATE.md +66 -0
- package/assets/toolkit/toolkit/templates/docs/product/PROJECT_INITIATION_TEMPLATE.md +98 -0
- package/assets/toolkit/toolkit/templates/docs/qa/QA_RELEASE_REPORT_TEMPLATE.md +61 -0
- package/assets/toolkit/toolkit/templates/docs/qa/TEST_CASE_CREATION_RULES.md +129 -0
- package/assets/toolkit/toolkit/templates/docs/qa/TEST_CASE_TEMPLATE.md +104 -0
- package/assets/toolkit/toolkit/templates/docs/specs/BA_SPEC_TEMPLATE.md +139 -0
- package/assets/toolkit/toolkit/templates/docs/specs/FLOW_ACTION_SPEC_CREATION_RULES.md +136 -0
- package/assets/toolkit/toolkit/templates/docs/specs/FLOW_ACTION_SPEC_TEMPLATE.md +160 -0
- package/bin/sdtk.js +15 -0
- package/package.json +47 -0
- package/src/commands/auth.js +85 -0
- package/src/commands/generate.js +177 -0
- package/src/commands/help.js +69 -0
- package/src/commands/init.js +73 -0
- package/src/index.js +56 -0
- package/src/lib/args.js +116 -0
- package/src/lib/errors.js +41 -0
- package/src/lib/github-access.js +68 -0
- package/src/lib/powershell.js +85 -0
- package/src/lib/state.js +83 -0
- package/src/lib/toolkit-payload.js +99 -0
package/src/lib/state.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const os = require("os");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const { execFileSync } = require("child_process");
|
|
7
|
+
|
|
8
|
+
function ensureDir(dirPath) {
|
|
9
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function getAuthFile() {
|
|
13
|
+
return path.join(os.homedir(), ".sdtkrc");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Harden file permissions so only the current user can read/write.
|
|
18
|
+
* - POSIX: chmod 600
|
|
19
|
+
* - Windows: icacls to grant only current user Full Control
|
|
20
|
+
* @returns {boolean} true if hardening succeeded, false otherwise.
|
|
21
|
+
*/
|
|
22
|
+
function hardenFilePermissions(filePath) {
|
|
23
|
+
try {
|
|
24
|
+
if (process.platform === "win32") {
|
|
25
|
+
const username = os.userInfo().username;
|
|
26
|
+
execFileSync("icacls", [
|
|
27
|
+
filePath,
|
|
28
|
+
"/inheritance:r",
|
|
29
|
+
"/grant:r",
|
|
30
|
+
`${username}:(F)`,
|
|
31
|
+
], { stdio: "ignore" });
|
|
32
|
+
} else {
|
|
33
|
+
fs.chmodSync(filePath, 0o600);
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
} catch (_err) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function readAuthState() {
|
|
42
|
+
const authFile = getAuthFile();
|
|
43
|
+
if (!fs.existsSync(authFile)) {
|
|
44
|
+
return { authenticated: false, token: "" };
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const payload = JSON.parse(fs.readFileSync(authFile, "utf8"));
|
|
48
|
+
const token = payload.github_token || "";
|
|
49
|
+
return { authenticated: token.length > 0, token };
|
|
50
|
+
} catch (_error) {
|
|
51
|
+
return { authenticated: false, token: "" };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Write auth state and harden file permissions.
|
|
57
|
+
* @returns {{ path: string, hardened: boolean }}
|
|
58
|
+
*/
|
|
59
|
+
function writeAuthState(token) {
|
|
60
|
+
const authFile = getAuthFile();
|
|
61
|
+
const payload = {
|
|
62
|
+
github_token: token,
|
|
63
|
+
updated_at: new Date().toISOString(),
|
|
64
|
+
};
|
|
65
|
+
fs.writeFileSync(authFile, JSON.stringify(payload, null, 2), "utf8");
|
|
66
|
+
const hardened = hardenFilePermissions(authFile);
|
|
67
|
+
return { path: authFile, hardened };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function clearAuthState() {
|
|
71
|
+
const authFile = getAuthFile();
|
|
72
|
+
if (fs.existsSync(authFile)) {
|
|
73
|
+
fs.unlinkSync(authFile);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = {
|
|
78
|
+
ensureDir,
|
|
79
|
+
getAuthFile,
|
|
80
|
+
readAuthState,
|
|
81
|
+
writeAuthState,
|
|
82
|
+
clearAuthState,
|
|
83
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const crypto = require("crypto");
|
|
6
|
+
const { IntegrityError } = require("./errors");
|
|
7
|
+
|
|
8
|
+
const PACKAGE_ROOT = path.resolve(__dirname, "..", "..");
|
|
9
|
+
const ASSETS_DIR = path.join(PACKAGE_ROOT, "assets", "toolkit");
|
|
10
|
+
const MANIFEST_PATH = path.join(
|
|
11
|
+
PACKAGE_ROOT,
|
|
12
|
+
"assets",
|
|
13
|
+
"manifest",
|
|
14
|
+
"toolkit-bundle.manifest.json"
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Load and parse the toolkit bundle manifest.
|
|
19
|
+
* @returns {Object} Parsed manifest object.
|
|
20
|
+
*/
|
|
21
|
+
function loadManifest() {
|
|
22
|
+
if (!fs.existsSync(MANIFEST_PATH)) {
|
|
23
|
+
throw new IntegrityError(
|
|
24
|
+
`Toolkit manifest not found: ${MANIFEST_PATH}\n` +
|
|
25
|
+
'Run "npm run build:payload" to sync toolkit assets.'
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const raw = fs.readFileSync(MANIFEST_PATH, "utf-8");
|
|
30
|
+
return JSON.parse(raw);
|
|
31
|
+
} catch (err) {
|
|
32
|
+
throw new IntegrityError(`Failed to parse manifest: ${err.message}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Compute SHA256 hash of a file.
|
|
38
|
+
* @param {string} filePath
|
|
39
|
+
* @returns {string} Lowercase hex hash.
|
|
40
|
+
*/
|
|
41
|
+
function hashFile(filePath) {
|
|
42
|
+
const data = fs.readFileSync(filePath);
|
|
43
|
+
return crypto.createHash("sha256").update(data).digest("hex");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Verify payload integrity against manifest.
|
|
48
|
+
* Checks all files exist and SHA256 hashes match.
|
|
49
|
+
* @throws {IntegrityError} on mismatch or missing file.
|
|
50
|
+
*/
|
|
51
|
+
function verify() {
|
|
52
|
+
const manifest = loadManifest();
|
|
53
|
+
|
|
54
|
+
if (!manifest.files || !Array.isArray(manifest.files)) {
|
|
55
|
+
throw new IntegrityError("Manifest has no files array.");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const errors = [];
|
|
59
|
+
|
|
60
|
+
for (const entry of manifest.files) {
|
|
61
|
+
const filePath = path.join(ASSETS_DIR, entry.path);
|
|
62
|
+
|
|
63
|
+
if (!fs.existsSync(filePath)) {
|
|
64
|
+
errors.push(`MISSING: ${entry.path}`);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const actualHash = hashFile(filePath);
|
|
69
|
+
if (actualHash !== entry.sha256) {
|
|
70
|
+
errors.push(
|
|
71
|
+
`HASH MISMATCH: ${entry.path}\n` +
|
|
72
|
+
` expected: ${entry.sha256}\n` +
|
|
73
|
+
` actual: ${actualHash}`
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (errors.length > 0) {
|
|
79
|
+
throw new IntegrityError(
|
|
80
|
+
`Toolkit payload integrity check failed:\n${errors.join("\n")}`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Resolve absolute path to a file inside the bundled toolkit payload.
|
|
87
|
+
* @param {string} relativePath - Path relative to assets/toolkit/ (e.g., "toolkit/install.ps1").
|
|
88
|
+
* @returns {string} Absolute path.
|
|
89
|
+
*/
|
|
90
|
+
function resolvePayloadFile(relativePath) {
|
|
91
|
+
return path.join(ASSETS_DIR, relativePath);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
module.exports = {
|
|
95
|
+
verify,
|
|
96
|
+
loadManifest,
|
|
97
|
+
resolvePayloadFile,
|
|
98
|
+
ASSETS_DIR,
|
|
99
|
+
};
|