safeword 0.6.2 → 0.6.4
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/dist/{check-PECCGHEA.js → check-ICZISZ3R.js} +41 -23
- package/dist/check-ICZISZ3R.js.map +1 -0
- package/dist/chunk-E5ZC6R5H.js +720 -0
- package/dist/chunk-E5ZC6R5H.js.map +1 -0
- package/dist/chunk-JGXYBPNM.js +454 -0
- package/dist/chunk-JGXYBPNM.js.map +1 -0
- package/dist/cli.js +7 -7
- package/dist/cli.js.map +1 -1
- package/dist/diff-FOJDBKKF.js +168 -0
- package/dist/diff-FOJDBKKF.js.map +1 -0
- package/dist/reset-JU2E65XN.js +74 -0
- package/dist/reset-JU2E65XN.js.map +1 -0
- package/dist/setup-UKMYK5TE.js +103 -0
- package/dist/setup-UKMYK5TE.js.map +1 -0
- package/dist/{sync-4XBMKLXS.js → sync-5MOXVTH4.js} +33 -32
- package/dist/sync-5MOXVTH4.js.map +1 -0
- package/dist/upgrade-NSLDFWNR.js +73 -0
- package/dist/upgrade-NSLDFWNR.js.map +1 -0
- package/package.json +14 -15
- package/templates/SAFEWORD.md +8 -28
- package/templates/hooks/stop-quality.sh +21 -9
- package/dist/check-PECCGHEA.js.map +0 -1
- package/dist/chunk-6CVTH67L.js +0 -43
- package/dist/chunk-6CVTH67L.js.map +0 -1
- package/dist/chunk-75FKNZUM.js +0 -15
- package/dist/chunk-75FKNZUM.js.map +0 -1
- package/dist/chunk-ARIAOK2F.js +0 -110
- package/dist/chunk-ARIAOK2F.js.map +0 -1
- package/dist/chunk-FRPJITGG.js +0 -35
- package/dist/chunk-FRPJITGG.js.map +0 -1
- package/dist/chunk-IWWBZVHT.js +0 -274
- package/dist/chunk-IWWBZVHT.js.map +0 -1
- package/dist/diff-ZACVJKOU.js +0 -171
- package/dist/diff-ZACVJKOU.js.map +0 -1
- package/dist/reset-5SRM3P6J.js +0 -145
- package/dist/reset-5SRM3P6J.js.map +0 -1
- package/dist/setup-65EVU5OT.js +0 -437
- package/dist/setup-65EVU5OT.js.map +0 -1
- package/dist/sync-4XBMKLXS.js.map +0 -1
- package/dist/upgrade-P3WX3ODU.js +0 -153
- package/dist/upgrade-P3WX3ODU.js.map +0 -1
- /package/templates/prompts/{review.md → quality-review.md} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "safeword",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"description": "CLI for setting up and managing safeword development environments",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -19,18 +19,6 @@
|
|
|
19
19
|
"engines": {
|
|
20
20
|
"node": ">=18"
|
|
21
21
|
},
|
|
22
|
-
"scripts": {
|
|
23
|
-
"build": "tsup",
|
|
24
|
-
"dev": "tsup --watch",
|
|
25
|
-
"test": "vitest run",
|
|
26
|
-
"test:e2e": "vitest run tests/e2e/",
|
|
27
|
-
"test:watch": "vitest",
|
|
28
|
-
"test:coverage": "vitest run --coverage",
|
|
29
|
-
"typecheck": "tsc --noEmit",
|
|
30
|
-
"lint": "eslint src tests",
|
|
31
|
-
"clean": "rm -rf dist",
|
|
32
|
-
"prepublishOnly": "npm audit --audit-level=high && npm run build && npm test"
|
|
33
|
-
},
|
|
34
22
|
"dependencies": {
|
|
35
23
|
"commander": "^12.1.0"
|
|
36
24
|
},
|
|
@@ -48,5 +36,16 @@
|
|
|
48
36
|
"claude-code"
|
|
49
37
|
],
|
|
50
38
|
"author": "",
|
|
51
|
-
"license": "MIT"
|
|
52
|
-
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsup",
|
|
42
|
+
"dev": "tsup --watch",
|
|
43
|
+
"test": "vitest run",
|
|
44
|
+
"test:e2e": "vitest run tests/e2e/",
|
|
45
|
+
"test:watch": "vitest",
|
|
46
|
+
"test:coverage": "vitest run --coverage",
|
|
47
|
+
"typecheck": "tsc --noEmit",
|
|
48
|
+
"lint": "eslint src tests",
|
|
49
|
+
"clean": "rm -rf dist"
|
|
50
|
+
}
|
|
51
|
+
}
|
package/templates/SAFEWORD.md
CHANGED
|
@@ -39,12 +39,11 @@ This file provides core guidance for all AI coding agent sessions. Organized mod
|
|
|
39
39
|
|
|
40
40
|
**Usage:**
|
|
41
41
|
|
|
42
|
-
**One-command setup (recommended):**
|
|
43
|
-
|
|
44
42
|
```bash
|
|
45
43
|
cd /path/to/your/project
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
npx safeword setup # Full installation
|
|
45
|
+
npx safeword check # Preview what would change
|
|
46
|
+
npx safeword upgrade # Update existing installation
|
|
48
47
|
```
|
|
49
48
|
|
|
50
49
|
**Auto-detection:** Automatically detects project type from package.json and config files:
|
|
@@ -56,22 +55,6 @@ bash ./framework/scripts/setup-claude.sh # Install Claude hooks (+
|
|
|
56
55
|
- TypeScript → if typescript in dependencies or tsconfig.json exists
|
|
57
56
|
- Minimal → otherwise
|
|
58
57
|
|
|
59
|
-
**Individual scripts (advanced):**
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
cd /path/to/your/project
|
|
63
|
-
bash ./framework/scripts/setup-linting.sh --typescript # Linting only
|
|
64
|
-
bash ./framework/scripts/setup-quality.sh # Quality review only
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
**Linting:** Auto-detects TypeScript, React, Astro from package.json.
|
|
68
|
-
|
|
69
|
-
- Two-file architecture:
|
|
70
|
-
- `.safeword/eslint/eslint-base.mjs` - Auto-generated every run (DO NOT EDIT)
|
|
71
|
-
- `eslint.config.mjs` - Your config (customize freely, never overwritten)
|
|
72
|
-
- After adding/removing frameworks: just re-run `bash setup-linting.sh`
|
|
73
|
-
- Override detection: `--no-typescript`, `--no-react`, `--no-astro`
|
|
74
|
-
|
|
75
58
|
**What they create:**
|
|
76
59
|
|
|
77
60
|
- `.safeword/SAFEWORD.md` - Global patterns and workflows (copied from this file)
|
|
@@ -99,21 +82,18 @@ bash ./framework/scripts/setup-quality.sh # Quality review only
|
|
|
99
82
|
|
|
100
83
|
**For teams:**
|
|
101
84
|
|
|
102
|
-
1.
|
|
103
|
-
2. In each project, run one command:
|
|
85
|
+
1. In each project, run:
|
|
104
86
|
```bash
|
|
105
87
|
cd /path/to/project
|
|
106
|
-
|
|
88
|
+
npx safeword setup
|
|
107
89
|
```
|
|
108
|
-
|
|
90
|
+
2. **Result**: Project becomes standalone with:
|
|
109
91
|
- `.safeword/SAFEWORD.md` - Global patterns (copy of this file)
|
|
110
92
|
- `.safeword/guides/` - Reference documentation
|
|
111
93
|
- `.claude/` - Hooks and commands
|
|
94
|
+
- `CLAUDE.md` - Project context that imports @./.safeword/SAFEWORD.md
|
|
112
95
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
4. **COMMIT to repo**: Commit `.safeword/` and `.claude/` for team consistency
|
|
116
|
-
5. **Delete source**: Can delete setup scripts/repo after running - project is fully portable
|
|
96
|
+
3. **COMMIT to repo**: Commit `.safeword/` and `.claude/` for team consistency
|
|
117
97
|
|
|
118
98
|
---
|
|
119
99
|
|
|
@@ -42,21 +42,31 @@ if [ -z "$msg_text" ]; then
|
|
|
42
42
|
exit 0
|
|
43
43
|
fi
|
|
44
44
|
|
|
45
|
-
# Extract
|
|
46
|
-
#
|
|
47
|
-
|
|
45
|
+
# Extract JSON blob containing our required fields (order-independent)
|
|
46
|
+
# Strategy: Use jq to find and validate the response summary object
|
|
47
|
+
# Look for object with exactly our three boolean fields anywhere in the text
|
|
48
|
+
json_blob=$(echo "$msg_text" | grep -oE '\{[^}]+\}' | while IFS= read -r candidate; do
|
|
49
|
+
if echo "$candidate" | jq -e '
|
|
50
|
+
type == "object" and
|
|
51
|
+
(.proposedChanges | type) == "boolean" and
|
|
52
|
+
(.madeChanges | type) == "boolean" and
|
|
53
|
+
(.askedQuestion | type) == "boolean"
|
|
54
|
+
' >/dev/null 2>&1; then
|
|
55
|
+
echo "$candidate"
|
|
56
|
+
fi
|
|
57
|
+
done | tail -1)
|
|
48
58
|
|
|
49
59
|
if [ -z "$json_blob" ]; then
|
|
50
|
-
# No JSON blob found - remind about required format
|
|
60
|
+
# No valid JSON blob found - remind about required format
|
|
51
61
|
echo "SAFEWORD: Response missing required JSON summary. Add to end of response:" >&2
|
|
52
62
|
echo '{"proposedChanges": boolean, "madeChanges": boolean, "askedQuestion": boolean}' >&2
|
|
53
63
|
exit 0
|
|
54
64
|
fi
|
|
55
65
|
|
|
56
|
-
# Parse the boolean values
|
|
57
|
-
proposed_changes=$(echo "$json_blob" | jq -r '.proposedChanges
|
|
58
|
-
made_changes=$(echo "$json_blob" | jq -r '.madeChanges
|
|
59
|
-
asked_question=$(echo "$json_blob" | jq -r '.askedQuestion
|
|
66
|
+
# Parse the boolean values (already validated, safe to extract)
|
|
67
|
+
proposed_changes=$(echo "$json_blob" | jq -r '.proposedChanges')
|
|
68
|
+
made_changes=$(echo "$json_blob" | jq -r '.madeChanges')
|
|
69
|
+
asked_question=$(echo "$json_blob" | jq -r '.askedQuestion')
|
|
60
70
|
|
|
61
71
|
# If asked a question, don't trigger review (waiting for user input)
|
|
62
72
|
if [ "$asked_question" = "true" ]; then
|
|
@@ -67,7 +77,9 @@ fi
|
|
|
67
77
|
if [ "$proposed_changes" = "true" ] || [ "$made_changes" = "true" ]; then
|
|
68
78
|
echo "SAFEWORD Quality Review:" >&2
|
|
69
79
|
echo "" >&2
|
|
70
|
-
echo "Double check and critique your work
|
|
80
|
+
echo "Double check and critique your work again just in case." >&2
|
|
81
|
+
echo "Assume you've never seen it before." >&2
|
|
82
|
+
echo "" >&2
|
|
71
83
|
echo "- Is it correct?" >&2
|
|
72
84
|
echo "- Is it elegant?" >&2
|
|
73
85
|
echo "- Does it follow latest docs/best practices?" >&2
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/check.ts"],"sourcesContent":["/**\n * Check command - Verify project health and configuration\n */\n\nimport { join } from 'node:path';\nimport { VERSION } from '../version.js';\nimport { exists, readFile, readFileSafe } from '../utils/fs.js';\nimport { info, success, warn, header, keyValue } from '../utils/output.js';\nimport { isNewerVersion } from '../utils/version.js';\n\nexport interface CheckOptions {\n offline?: boolean;\n}\n\ninterface HealthStatus {\n configured: boolean;\n projectVersion: string | null;\n cliVersion: string;\n updateAvailable: boolean;\n latestVersion: string | null;\n issues: string[];\n}\n\n/**\n * Check for latest version from npm (with timeout)\n */\nasync function checkLatestVersion(timeout = 3000): Promise<string | null> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n const response = await fetch('https://registry.npmjs.org/safeword/latest', {\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) return null;\n\n const data = (await response.json()) as { version?: string };\n return data.version ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check project configuration health\n */\nfunction checkHealth(cwd: string): HealthStatus {\n const safewordDir = join(cwd, '.safeword');\n const issues: string[] = [];\n\n // Check if configured\n if (!exists(safewordDir)) {\n return {\n configured: false,\n projectVersion: null,\n cliVersion: VERSION,\n updateAvailable: false,\n latestVersion: null,\n issues: [],\n };\n }\n\n // Read project version\n const versionPath = join(safewordDir, 'version');\n const projectVersion = readFileSafe(versionPath)?.trim() ?? null;\n\n // Check for required files\n const requiredFiles = ['SAFEWORD.md', 'version', 'hooks/session-verify-agents.sh'];\n\n for (const file of requiredFiles) {\n if (!exists(join(safewordDir, file))) {\n issues.push(`Missing: .safeword/${file}`);\n }\n }\n\n // Check AGENTS.md link\n const agentsMdPath = join(cwd, 'AGENTS.md');\n if (exists(agentsMdPath)) {\n const content = readFile(agentsMdPath);\n if (!content.includes('@./.safeword/SAFEWORD.md')) {\n issues.push('AGENTS.md missing safeword link');\n }\n } else {\n issues.push('AGENTS.md file missing');\n }\n\n // Check .claude/settings.json\n const settingsPath = join(cwd, '.claude', 'settings.json');\n if (!exists(settingsPath)) {\n issues.push('Missing: .claude/settings.json');\n }\n\n return {\n configured: true,\n projectVersion,\n cliVersion: VERSION,\n updateAvailable: false,\n latestVersion: null,\n issues,\n };\n}\n\nexport async function check(options: CheckOptions): Promise<void> {\n const cwd = process.cwd();\n\n header('Safeword Health Check');\n\n const health = checkHealth(cwd);\n\n // Not configured\n if (!health.configured) {\n info('Not configured. Run `safeword setup` to initialize.');\n return;\n }\n\n // Show versions\n keyValue('Safeword CLI', `v${health.cliVersion}`);\n keyValue('Project config', health.projectVersion ? `v${health.projectVersion}` : 'unknown');\n\n // Check for updates (unless offline)\n if (!options.offline) {\n info('\\nChecking for updates...');\n const latestVersion = await checkLatestVersion();\n\n if (latestVersion) {\n health.latestVersion = latestVersion;\n health.updateAvailable = isNewerVersion(health.cliVersion, latestVersion);\n\n if (health.updateAvailable) {\n warn(`Update available: v${latestVersion}`);\n info('Run `npm install -g safeword` to upgrade');\n } else {\n success('CLI is up to date');\n }\n } else {\n warn(\"Couldn't check for updates (offline?)\");\n }\n } else {\n info('\\nSkipped update check (offline mode)');\n }\n\n // Check project version vs CLI version\n if (health.projectVersion && isNewerVersion(health.cliVersion, health.projectVersion)) {\n warn(`Project config (v${health.projectVersion}) is newer than CLI (v${health.cliVersion})`);\n info('Consider upgrading the CLI');\n } else if (health.projectVersion && isNewerVersion(health.projectVersion, health.cliVersion)) {\n info(`\\nUpgrade available for project config`);\n info(\n `Run \\`safeword upgrade\\` to update from v${health.projectVersion} to v${health.cliVersion}`,\n );\n }\n\n // Show issues\n if (health.issues.length > 0) {\n header('Issues Found');\n for (const issue of health.issues) {\n warn(issue);\n }\n info('\\nRun `safeword upgrade` to repair configuration');\n } else {\n success('\\nConfiguration is healthy');\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/chunk-6CVTH67L.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
// src/utils/project-detector.ts
|
|
2
|
-
function detectProjectType(packageJson) {
|
|
3
|
-
const deps = packageJson.dependencies || {};
|
|
4
|
-
const devDeps = packageJson.devDependencies || {};
|
|
5
|
-
const allDeps = { ...deps, ...devDeps };
|
|
6
|
-
const hasTypescript = "typescript" in allDeps;
|
|
7
|
-
const hasReact = "react" in deps || "react" in devDeps;
|
|
8
|
-
const hasNextJs = "next" in deps;
|
|
9
|
-
const hasAstro = "astro" in deps || "astro" in devDeps;
|
|
10
|
-
const hasVue = "vue" in deps || "vue" in devDeps;
|
|
11
|
-
const hasNuxt = "nuxt" in deps;
|
|
12
|
-
const hasSvelte = "svelte" in deps || "svelte" in devDeps;
|
|
13
|
-
const hasSvelteKit = "@sveltejs/kit" in deps || "@sveltejs/kit" in devDeps;
|
|
14
|
-
const hasElectron = "electron" in deps || "electron" in devDeps;
|
|
15
|
-
const hasVitest = "vitest" in devDeps;
|
|
16
|
-
const hasPlaywright = "@playwright/test" in devDeps;
|
|
17
|
-
const hasTailwind = "tailwindcss" in allDeps;
|
|
18
|
-
const hasEntryPoints = !!(packageJson.main || packageJson.module || packageJson.exports);
|
|
19
|
-
const isPublishable = hasEntryPoints && packageJson.private !== true;
|
|
20
|
-
return {
|
|
21
|
-
typescript: hasTypescript,
|
|
22
|
-
react: hasReact || hasNextJs,
|
|
23
|
-
// Next.js implies React
|
|
24
|
-
nextjs: hasNextJs,
|
|
25
|
-
astro: hasAstro,
|
|
26
|
-
vue: hasVue || hasNuxt,
|
|
27
|
-
// Nuxt implies Vue
|
|
28
|
-
nuxt: hasNuxt,
|
|
29
|
-
svelte: hasSvelte || hasSvelteKit,
|
|
30
|
-
// SvelteKit implies Svelte
|
|
31
|
-
sveltekit: hasSvelteKit,
|
|
32
|
-
electron: hasElectron,
|
|
33
|
-
vitest: hasVitest,
|
|
34
|
-
playwright: hasPlaywright,
|
|
35
|
-
tailwind: hasTailwind,
|
|
36
|
-
publishableLibrary: isPublishable
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export {
|
|
41
|
-
detectProjectType
|
|
42
|
-
};
|
|
43
|
-
//# sourceMappingURL=chunk-6CVTH67L.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/project-detector.ts"],"sourcesContent":["/**\n * Project type detection from package.json\n *\n * Detects frameworks and tools used in the project to configure\n * appropriate linting rules.\n */\n\nexport interface PackageJson {\n name?: string;\n version?: string;\n private?: boolean;\n main?: string;\n module?: string;\n exports?: unknown;\n types?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\nexport interface ProjectType {\n typescript: boolean;\n react: boolean;\n nextjs: boolean;\n astro: boolean;\n vue: boolean;\n nuxt: boolean;\n svelte: boolean;\n sveltekit: boolean;\n electron: boolean;\n vitest: boolean;\n playwright: boolean;\n tailwind: boolean;\n publishableLibrary: boolean;\n}\n\n/**\n * Detects project type from package.json contents\n */\nexport function detectProjectType(packageJson: PackageJson): ProjectType {\n const deps = packageJson.dependencies || {};\n const devDeps = packageJson.devDependencies || {};\n const allDeps = { ...deps, ...devDeps };\n\n const hasTypescript = 'typescript' in allDeps;\n const hasReact = 'react' in deps || 'react' in devDeps;\n const hasNextJs = 'next' in deps;\n const hasAstro = 'astro' in deps || 'astro' in devDeps;\n const hasVue = 'vue' in deps || 'vue' in devDeps;\n const hasNuxt = 'nuxt' in deps;\n const hasSvelte = 'svelte' in deps || 'svelte' in devDeps;\n const hasSvelteKit = '@sveltejs/kit' in deps || '@sveltejs/kit' in devDeps;\n const hasElectron = 'electron' in deps || 'electron' in devDeps;\n const hasVitest = 'vitest' in devDeps;\n const hasPlaywright = '@playwright/test' in devDeps;\n const hasTailwind = 'tailwindcss' in allDeps;\n\n // Publishable library: has entry points and is not marked private\n const hasEntryPoints = !!(packageJson.main || packageJson.module || packageJson.exports);\n const isPublishable = hasEntryPoints && packageJson.private !== true;\n\n return {\n typescript: hasTypescript,\n react: hasReact || hasNextJs, // Next.js implies React\n nextjs: hasNextJs,\n astro: hasAstro,\n vue: hasVue || hasNuxt, // Nuxt implies Vue\n nuxt: hasNuxt,\n svelte: hasSvelte || hasSvelteKit, // SvelteKit implies Svelte\n sveltekit: hasSvelteKit,\n electron: hasElectron,\n vitest: hasVitest,\n playwright: hasPlaywright,\n tailwind: hasTailwind,\n publishableLibrary: isPublishable,\n };\n}\n"],"mappings":";AAsCO,SAAS,kBAAkB,aAAuC;AACvE,QAAM,OAAO,YAAY,gBAAgB,CAAC;AAC1C,QAAM,UAAU,YAAY,mBAAmB,CAAC;AAChD,QAAM,UAAU,EAAE,GAAG,MAAM,GAAG,QAAQ;AAEtC,QAAM,gBAAgB,gBAAgB;AACtC,QAAM,WAAW,WAAW,QAAQ,WAAW;AAC/C,QAAM,YAAY,UAAU;AAC5B,QAAM,WAAW,WAAW,QAAQ,WAAW;AAC/C,QAAM,SAAS,SAAS,QAAQ,SAAS;AACzC,QAAM,UAAU,UAAU;AAC1B,QAAM,YAAY,YAAY,QAAQ,YAAY;AAClD,QAAM,eAAe,mBAAmB,QAAQ,mBAAmB;AACnE,QAAM,cAAc,cAAc,QAAQ,cAAc;AACxD,QAAM,YAAY,YAAY;AAC9B,QAAM,gBAAgB,sBAAsB;AAC5C,QAAM,cAAc,iBAAiB;AAGrC,QAAM,iBAAiB,CAAC,EAAE,YAAY,QAAQ,YAAY,UAAU,YAAY;AAChF,QAAM,gBAAgB,kBAAkB,YAAY,YAAY;AAEhE,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,OAAO,YAAY;AAAA;AAAA,IACnB,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,KAAK,UAAU;AAAA;AAAA,IACf,MAAM;AAAA,IACN,QAAQ,aAAa;AAAA;AAAA,IACrB,WAAW;AAAA,IACX,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,oBAAoB;AAAA,EACtB;AACF;","names":[]}
|
package/dist/chunk-75FKNZUM.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
exists
|
|
3
|
-
} from "./chunk-ARIAOK2F.js";
|
|
4
|
-
|
|
5
|
-
// src/utils/git.ts
|
|
6
|
-
import { execSync } from "child_process";
|
|
7
|
-
import { join } from "path";
|
|
8
|
-
function isGitRepo(cwd) {
|
|
9
|
-
return exists(join(cwd, ".git"));
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export {
|
|
13
|
-
isGitRepo
|
|
14
|
-
};
|
|
15
|
-
//# sourceMappingURL=chunk-75FKNZUM.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/git.ts"],"sourcesContent":["/**\n * Git utilities for CLI operations\n */\n\nimport { execSync } from 'node:child_process';\nimport { join } from 'node:path';\nimport { exists, readFile, writeFile, ensureDir, makeExecutable } from './fs.js';\n\nconst MARKER_START = '# SAFEWORD_ARCH_CHECK_START';\nconst MARKER_END = '# SAFEWORD_ARCH_CHECK_END';\n\n/**\n * Check if directory is a git repository\n */\nexport function isGitRepo(cwd: string): boolean {\n return exists(join(cwd, '.git'));\n}\n\n/**\n * Initialize a git repository\n */\nexport function initGitRepo(cwd: string): void {\n execSync('git init', { cwd, stdio: 'pipe' });\n}\n\n/**\n * Get the pre-commit hook content to add\n */\nfunction getHookContent(): string {\n return `\n${MARKER_START}\n# Safeword pre-commit linting\n# This section is managed by safeword - do not edit manually\nif [ -f \".safeword/hooks/git-pre-commit.sh\" ]; then\n bash .safeword/hooks/git-pre-commit.sh\nfi\n${MARKER_END}\n`;\n}\n\n/**\n * Install safeword markers into pre-commit hook\n */\nexport function installGitHook(cwd: string): void {\n const hooksDir = join(cwd, '.git', 'hooks');\n const hookPath = join(hooksDir, 'pre-commit');\n\n ensureDir(hooksDir);\n\n let content = '';\n\n if (exists(hookPath)) {\n content = readFile(hookPath);\n\n // Check if already has safeword markers\n if (content.includes(MARKER_START)) {\n // Remove existing safeword section and re-add (update)\n content = removeMarkerSection(content);\n }\n } else {\n // Create new hook file with shebang\n content = '#!/bin/bash\\n';\n }\n\n // Add safeword section\n content = content.trimEnd() + '\\n' + getHookContent();\n\n writeFile(hookPath, content);\n makeExecutable(hookPath);\n}\n\n/**\n * Remove safeword markers from pre-commit hook\n */\nexport function removeGitHook(cwd: string): void {\n const hookPath = join(cwd, '.git', 'hooks', 'pre-commit');\n\n if (!exists(hookPath)) return;\n\n let content = readFile(hookPath);\n\n if (!content.includes(MARKER_START)) return;\n\n content = removeMarkerSection(content);\n\n // If only shebang remains, we could delete the file\n // but safer to leave it\n writeFile(hookPath, content);\n}\n\n/**\n * Remove the section between markers (inclusive)\n */\nfunction removeMarkerSection(content: string): string {\n const lines = content.split('\\n');\n const result: string[] = [];\n let inMarkerSection = false;\n\n for (const line of lines) {\n if (line.includes(MARKER_START)) {\n inMarkerSection = true;\n continue;\n }\n if (line.includes(MARKER_END)) {\n inMarkerSection = false;\n continue;\n }\n if (!inMarkerSection) {\n result.push(line);\n }\n }\n\n return result.join('\\n').trim() + '\\n';\n}\n\n/**\n * Check if git hooks have safeword markers\n */\nexport function hasGitHook(cwd: string): boolean {\n const hookPath = join(cwd, '.git', 'hooks', 'pre-commit');\n if (!exists(hookPath)) return false;\n const content = readFile(hookPath);\n return content.includes(MARKER_START);\n}\n"],"mappings":";;;;;AAIA,SAAS,gBAAgB;AACzB,SAAS,YAAY;AASd,SAAS,UAAU,KAAsB;AAC9C,SAAO,OAAO,KAAK,KAAK,MAAM,CAAC;AACjC;","names":[]}
|
package/dist/chunk-ARIAOK2F.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
// src/utils/fs.ts
|
|
2
|
-
import {
|
|
3
|
-
existsSync,
|
|
4
|
-
mkdirSync,
|
|
5
|
-
readFileSync,
|
|
6
|
-
writeFileSync,
|
|
7
|
-
rmSync,
|
|
8
|
-
readdirSync,
|
|
9
|
-
statSync,
|
|
10
|
-
chmodSync,
|
|
11
|
-
copyFileSync
|
|
12
|
-
} from "fs";
|
|
13
|
-
import { join, dirname } from "path";
|
|
14
|
-
import { fileURLToPath } from "url";
|
|
15
|
-
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
|
-
function getTemplatesDir() {
|
|
17
|
-
const fromDist = join(__dirname, "..", "templates");
|
|
18
|
-
const fallback = join(__dirname, "..", "..", "templates");
|
|
19
|
-
if (existsSync(fromDist)) return fromDist;
|
|
20
|
-
if (existsSync(fallback)) return fallback;
|
|
21
|
-
throw new Error("Templates directory not found");
|
|
22
|
-
}
|
|
23
|
-
function exists(path) {
|
|
24
|
-
return existsSync(path);
|
|
25
|
-
}
|
|
26
|
-
function ensureDir(path) {
|
|
27
|
-
if (!existsSync(path)) {
|
|
28
|
-
mkdirSync(path, { recursive: true });
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
function readFile(path) {
|
|
32
|
-
return readFileSync(path, "utf-8");
|
|
33
|
-
}
|
|
34
|
-
function readFileSafe(path) {
|
|
35
|
-
if (!existsSync(path)) return null;
|
|
36
|
-
return readFileSync(path, "utf-8");
|
|
37
|
-
}
|
|
38
|
-
function writeFile(path, content) {
|
|
39
|
-
ensureDir(dirname(path));
|
|
40
|
-
writeFileSync(path, content);
|
|
41
|
-
}
|
|
42
|
-
function remove(path) {
|
|
43
|
-
if (existsSync(path)) {
|
|
44
|
-
rmSync(path, { recursive: true, force: true });
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
function listDir(path) {
|
|
48
|
-
if (!existsSync(path)) return [];
|
|
49
|
-
return readdirSync(path);
|
|
50
|
-
}
|
|
51
|
-
function copyFile(src, dest) {
|
|
52
|
-
ensureDir(dirname(dest));
|
|
53
|
-
copyFileSync(src, dest);
|
|
54
|
-
}
|
|
55
|
-
function copyDir(src, dest) {
|
|
56
|
-
ensureDir(dest);
|
|
57
|
-
const entries = readdirSync(src, { withFileTypes: true });
|
|
58
|
-
for (const entry of entries) {
|
|
59
|
-
const srcPath = join(src, entry.name);
|
|
60
|
-
const destPath = join(dest, entry.name);
|
|
61
|
-
if (entry.isDirectory()) {
|
|
62
|
-
copyDir(srcPath, destPath);
|
|
63
|
-
} else {
|
|
64
|
-
copyFileSync(srcPath, destPath);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
function makeScriptsExecutable(dirPath) {
|
|
69
|
-
if (!existsSync(dirPath)) return;
|
|
70
|
-
for (const file of readdirSync(dirPath)) {
|
|
71
|
-
if (file.endsWith(".sh")) {
|
|
72
|
-
chmodSync(join(dirPath, file), 493);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
function readJson(path) {
|
|
77
|
-
const content = readFileSafe(path);
|
|
78
|
-
if (!content) return null;
|
|
79
|
-
try {
|
|
80
|
-
return JSON.parse(content);
|
|
81
|
-
} catch {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
function writeJson(path, data) {
|
|
86
|
-
writeFile(path, JSON.stringify(data, null, 2) + "\n");
|
|
87
|
-
}
|
|
88
|
-
function updateJson(path, updater) {
|
|
89
|
-
const existing = readJson(path);
|
|
90
|
-
const updated = updater(existing);
|
|
91
|
-
writeJson(path, updated);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export {
|
|
95
|
-
getTemplatesDir,
|
|
96
|
-
exists,
|
|
97
|
-
ensureDir,
|
|
98
|
-
readFile,
|
|
99
|
-
readFileSafe,
|
|
100
|
-
writeFile,
|
|
101
|
-
remove,
|
|
102
|
-
listDir,
|
|
103
|
-
copyFile,
|
|
104
|
-
copyDir,
|
|
105
|
-
makeScriptsExecutable,
|
|
106
|
-
readJson,
|
|
107
|
-
writeJson,
|
|
108
|
-
updateJson
|
|
109
|
-
};
|
|
110
|
-
//# sourceMappingURL=chunk-ARIAOK2F.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/fs.ts"],"sourcesContent":["/**\n * File system utilities for CLI operations\n */\n\nimport {\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n rmSync,\n readdirSync,\n statSync,\n chmodSync,\n copyFileSync,\n} from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n// Get the directory of this module (for locating templates)\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n/**\n * Get path to bundled templates directory.\n * Works in both development (src/) and production (dist/) contexts.\n */\nexport function getTemplatesDir(): string {\n // When running from dist/, __dirname is packages/cli/dist/\n // Templates are at packages/cli/templates/ (one level up)\n const fromDist = join(__dirname, '..', 'templates');\n\n // Fallback path for edge cases\n const fallback = join(__dirname, '..', '..', 'templates');\n\n if (existsSync(fromDist)) return fromDist;\n if (existsSync(fallback)) return fallback;\n\n throw new Error('Templates directory not found');\n}\n\n/**\n * Check if a path exists\n */\nexport function exists(path: string): boolean {\n return existsSync(path);\n}\n\n/**\n * Check if path is a directory\n */\nexport function isDirectory(path: string): boolean {\n return existsSync(path) && statSync(path).isDirectory();\n}\n\n/**\n * Create directory recursively\n */\nexport function ensureDir(path: string): void {\n if (!existsSync(path)) {\n mkdirSync(path, { recursive: true });\n }\n}\n\n/**\n * Read file as string\n */\nexport function readFile(path: string): string {\n return readFileSync(path, 'utf-8');\n}\n\n/**\n * Read file as string, return null if not exists\n */\nexport function readFileSafe(path: string): string | null {\n if (!existsSync(path)) return null;\n return readFileSync(path, 'utf-8');\n}\n\n/**\n * Write file, creating parent directories if needed\n */\nexport function writeFile(path: string, content: string): void {\n ensureDir(dirname(path));\n writeFileSync(path, content);\n}\n\n/**\n * Remove file or directory recursively\n */\nexport function remove(path: string): void {\n if (existsSync(path)) {\n rmSync(path, { recursive: true, force: true });\n }\n}\n\n/**\n * List files in directory\n */\nexport function listDir(path: string): string[] {\n if (!existsSync(path)) return [];\n return readdirSync(path);\n}\n\n/**\n * Copy a single file\n */\nexport function copyFile(src: string, dest: string): void {\n ensureDir(dirname(dest));\n copyFileSync(src, dest);\n}\n\n/**\n * Copy directory recursively\n */\nexport function copyDir(src: string, dest: string): void {\n ensureDir(dest);\n const entries = readdirSync(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = join(src, entry.name);\n const destPath = join(dest, entry.name);\n\n if (entry.isDirectory()) {\n copyDir(srcPath, destPath);\n } else {\n copyFileSync(srcPath, destPath);\n }\n }\n}\n\n/**\n * Make file executable\n */\nexport function makeExecutable(path: string): void {\n chmodSync(path, 0o755);\n}\n\n/**\n * Make all shell scripts in a directory executable\n */\nexport function makeScriptsExecutable(dirPath: string): void {\n if (!existsSync(dirPath)) return;\n for (const file of readdirSync(dirPath)) {\n if (file.endsWith('.sh')) {\n chmodSync(join(dirPath, file), 0o755);\n }\n }\n}\n\n/**\n * Read JSON file\n */\nexport function readJson<T = unknown>(path: string): T | null {\n const content = readFileSafe(path);\n if (!content) return null;\n try {\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\n/**\n * Write JSON file with formatting\n */\nexport function writeJson(path: string, data: unknown): void {\n writeFile(path, JSON.stringify(data, null, 2) + '\\n');\n}\n\n/**\n * Update JSON file, merging with existing content\n */\nexport function updateJson<T extends Record<string, unknown>>(\n path: string,\n updater: (existing: T | null) => T,\n): void {\n const existing = readJson<T>(path);\n const updated = updater(existing);\n writeJson(path, updated);\n}\n"],"mappings":";AAIA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,MAAM,eAAe;AAC9B,SAAS,qBAAqB;AAG9B,IAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AAMjD,SAAS,kBAA0B;AAGxC,QAAM,WAAW,KAAK,WAAW,MAAM,WAAW;AAGlD,QAAM,WAAW,KAAK,WAAW,MAAM,MAAM,WAAW;AAExD,MAAI,WAAW,QAAQ,EAAG,QAAO;AACjC,MAAI,WAAW,QAAQ,EAAG,QAAO;AAEjC,QAAM,IAAI,MAAM,+BAA+B;AACjD;AAKO,SAAS,OAAO,MAAuB;AAC5C,SAAO,WAAW,IAAI;AACxB;AAYO,SAAS,UAAU,MAAoB;AAC5C,MAAI,CAAC,WAAW,IAAI,GAAG;AACrB,cAAU,MAAM,EAAE,WAAW,KAAK,CAAC;AAAA,EACrC;AACF;AAKO,SAAS,SAAS,MAAsB;AAC7C,SAAO,aAAa,MAAM,OAAO;AACnC;AAKO,SAAS,aAAa,MAA6B;AACxD,MAAI,CAAC,WAAW,IAAI,EAAG,QAAO;AAC9B,SAAO,aAAa,MAAM,OAAO;AACnC;AAKO,SAAS,UAAU,MAAc,SAAuB;AAC7D,YAAU,QAAQ,IAAI,CAAC;AACvB,gBAAc,MAAM,OAAO;AAC7B;AAKO,SAAS,OAAO,MAAoB;AACzC,MAAI,WAAW,IAAI,GAAG;AACpB,WAAO,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EAC/C;AACF;AAKO,SAAS,QAAQ,MAAwB;AAC9C,MAAI,CAAC,WAAW,IAAI,EAAG,QAAO,CAAC;AAC/B,SAAO,YAAY,IAAI;AACzB;AAKO,SAAS,SAAS,KAAa,MAAoB;AACxD,YAAU,QAAQ,IAAI,CAAC;AACvB,eAAa,KAAK,IAAI;AACxB;AAKO,SAAS,QAAQ,KAAa,MAAoB;AACvD,YAAU,IAAI;AACd,QAAM,UAAU,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AAExD,aAAW,SAAS,SAAS;AAC3B,UAAM,UAAU,KAAK,KAAK,MAAM,IAAI;AACpC,UAAM,WAAW,KAAK,MAAM,MAAM,IAAI;AAEtC,QAAI,MAAM,YAAY,GAAG;AACvB,cAAQ,SAAS,QAAQ;AAAA,IAC3B,OAAO;AACL,mBAAa,SAAS,QAAQ;AAAA,IAChC;AAAA,EACF;AACF;AAYO,SAAS,sBAAsB,SAAuB;AAC3D,MAAI,CAAC,WAAW,OAAO,EAAG;AAC1B,aAAW,QAAQ,YAAY,OAAO,GAAG;AACvC,QAAI,KAAK,SAAS,KAAK,GAAG;AACxB,gBAAU,KAAK,SAAS,IAAI,GAAG,GAAK;AAAA,IACtC;AAAA,EACF;AACF;AAKO,SAAS,SAAsB,MAAwB;AAC5D,QAAM,UAAU,aAAa,IAAI;AACjC,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI;AACF,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAAS,UAAU,MAAc,MAAqB;AAC3D,YAAU,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC,IAAI,IAAI;AACtD;AAKO,SAAS,WACd,MACA,SACM;AACN,QAAM,WAAW,SAAY,IAAI;AACjC,QAAM,UAAU,QAAQ,QAAQ;AAChC,YAAU,MAAM,OAAO;AACzB;","names":[]}
|
package/dist/chunk-FRPJITGG.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
// src/utils/output.ts
|
|
2
|
-
function info(message) {
|
|
3
|
-
console.log(message);
|
|
4
|
-
}
|
|
5
|
-
function success(message) {
|
|
6
|
-
console.log(`\u2713 ${message}`);
|
|
7
|
-
}
|
|
8
|
-
function warn(message) {
|
|
9
|
-
console.warn(`\u26A0 ${message}`);
|
|
10
|
-
}
|
|
11
|
-
function error(message) {
|
|
12
|
-
console.error(`\u2717 ${message}`);
|
|
13
|
-
}
|
|
14
|
-
function header(title) {
|
|
15
|
-
console.log(`
|
|
16
|
-
${title}`);
|
|
17
|
-
console.log("\u2500".repeat(title.length));
|
|
18
|
-
}
|
|
19
|
-
function listItem(item, indent = 2) {
|
|
20
|
-
console.log(`${" ".repeat(indent)}\u2022 ${item}`);
|
|
21
|
-
}
|
|
22
|
-
function keyValue(key, value) {
|
|
23
|
-
console.log(` ${key}: ${value}`);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export {
|
|
27
|
-
info,
|
|
28
|
-
success,
|
|
29
|
-
warn,
|
|
30
|
-
error,
|
|
31
|
-
header,
|
|
32
|
-
listItem,
|
|
33
|
-
keyValue
|
|
34
|
-
};
|
|
35
|
-
//# sourceMappingURL=chunk-FRPJITGG.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/output.ts"],"sourcesContent":["/**\n * Console output utilities for consistent CLI messaging\n */\n\n/**\n * Print info message\n */\nexport function info(message: string): void {\n console.log(message);\n}\n\n/**\n * Print success message\n */\nexport function success(message: string): void {\n console.log(`✓ ${message}`);\n}\n\n/**\n * Print warning message\n */\nexport function warn(message: string): void {\n console.warn(`⚠ ${message}`);\n}\n\n/**\n * Print error message to stderr\n */\nexport function error(message: string): void {\n console.error(`✗ ${message}`);\n}\n\n/**\n * Print a blank line\n */\nexport function blank(): void {\n console.log('');\n}\n\n/**\n * Print a section header\n */\nexport function header(title: string): void {\n console.log(`\\n${title}`);\n console.log('─'.repeat(title.length));\n}\n\n/**\n * Print a list item\n */\nexport function listItem(item: string, indent = 2): void {\n console.log(`${' '.repeat(indent)}• ${item}`);\n}\n\n/**\n * Print key-value pair\n */\nexport function keyValue(key: string, value: string): void {\n console.log(` ${key}: ${value}`);\n}\n"],"mappings":";AAOO,SAAS,KAAK,SAAuB;AAC1C,UAAQ,IAAI,OAAO;AACrB;AAKO,SAAS,QAAQ,SAAuB;AAC7C,UAAQ,IAAI,UAAK,OAAO,EAAE;AAC5B;AAKO,SAAS,KAAK,SAAuB;AAC1C,UAAQ,KAAK,UAAK,OAAO,EAAE;AAC7B;AAKO,SAAS,MAAM,SAAuB;AAC3C,UAAQ,MAAM,UAAK,OAAO,EAAE;AAC9B;AAYO,SAAS,OAAO,OAAqB;AAC1C,UAAQ,IAAI;AAAA,EAAK,KAAK,EAAE;AACxB,UAAQ,IAAI,SAAI,OAAO,MAAM,MAAM,CAAC;AACtC;AAKO,SAAS,SAAS,MAAc,SAAS,GAAS;AACvD,UAAQ,IAAI,GAAG,IAAI,OAAO,MAAM,CAAC,UAAK,IAAI,EAAE;AAC9C;AAKO,SAAS,SAAS,KAAa,OAAqB;AACzD,UAAQ,IAAI,KAAK,GAAG,KAAK,KAAK,EAAE;AAClC;","names":[]}
|