@staff0rd/assist 0.10.1 → 0.14.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 +55 -44
- package/dist/commands/deploy/build.yml +25 -25
- package/dist/commands/deploy/init.ts +29 -9
- package/dist/commands/deploy/redirect.ts +39 -0
- package/dist/commands/enable-ralph/index.ts +2 -7
- package/dist/commands/lint/init.ts +5 -7
- package/dist/index.js +399 -275
- package/package.json +53 -49
package/README.md
CHANGED
|
@@ -1,44 +1,55 @@
|
|
|
1
|
-
# assist
|
|
2
|
-
|
|
3
|
-
A CLI tool for enforcing determinism in LLM development workflow automation.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
#
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- `assist
|
|
34
|
-
- `assist
|
|
35
|
-
- `assist
|
|
36
|
-
- `assist
|
|
37
|
-
- `assist
|
|
38
|
-
- `assist
|
|
39
|
-
- `assist
|
|
40
|
-
- `assist
|
|
41
|
-
- `assist
|
|
42
|
-
- `assist
|
|
43
|
-
- `assist
|
|
44
|
-
|
|
1
|
+
# assist
|
|
2
|
+
|
|
3
|
+
A CLI tool for enforcing determinism in LLM development workflow automation.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
You can install `assist` globally using npm:
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install -g @staff0rd/assist
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Local Development
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Clone the repository
|
|
16
|
+
git clone git@github.com:staff0rd/assist.git
|
|
17
|
+
cd assist
|
|
18
|
+
|
|
19
|
+
# Install dependencies
|
|
20
|
+
npm install
|
|
21
|
+
|
|
22
|
+
# Build the project
|
|
23
|
+
npm run build
|
|
24
|
+
|
|
25
|
+
# Install globally
|
|
26
|
+
npm install -g .
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
After installation, the `assist` command will be available globally.
|
|
30
|
+
|
|
31
|
+
## Commands
|
|
32
|
+
|
|
33
|
+
- `assist init` - Initialize project with VS Code and verify configurations
|
|
34
|
+
- `assist new` - Initialize a new Vite React TypeScript project
|
|
35
|
+
- `assist sync` - Copy command files to `~/.claude/commands`
|
|
36
|
+
- `assist commit <message>` - Create a git commit with validation
|
|
37
|
+
- `assist prs` - List pull requests for the current repository
|
|
38
|
+
- `assist run <name>` - Run a configured command from assist.yml
|
|
39
|
+
- `assist run add` - Add a new run configuration to assist.yml
|
|
40
|
+
- `assist update` - Update claude-code to the latest version
|
|
41
|
+
- `assist verify` - Run all verify:* scripts from package.json in parallel
|
|
42
|
+
- `assist verify init` - Add verify scripts to a project
|
|
43
|
+
- `assist verify hardcoded-colors` - Check for hardcoded hex colors in src/
|
|
44
|
+
- `assist lint` - Run lint checks for conventions not enforced by biomejs
|
|
45
|
+
- `assist lint init` - Initialize Biome with standard linter config
|
|
46
|
+
- `assist refactor check [pattern]` - Check for files that exceed the maximum line count
|
|
47
|
+
- `assist refactor ignore <file>` - Add a file to the refactor ignore list
|
|
48
|
+
- `assist devlog list` - Group git commits by date
|
|
49
|
+
- `assist devlog next` - Show commits for the day after the last versioned entry
|
|
50
|
+
- `assist devlog skip <date>` - Add a date to the skip list
|
|
51
|
+
- `assist devlog version` - Show current repo name and version info
|
|
52
|
+
- `assist vscode init` - Add VS Code configuration files
|
|
53
|
+
- `assist deploy init` - Initialize Netlify project and configure deployment
|
|
54
|
+
- `assist status-line` - Format Claude Code status line from JSON stdin
|
|
55
|
+
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
name: Build and Deploy to Netlify
|
|
2
|
-
on:
|
|
3
|
-
push:
|
|
4
|
-
branches:
|
|
5
|
-
- main
|
|
6
|
-
jobs:
|
|
7
|
-
build_and_deploy:
|
|
8
|
-
runs-on: ubuntu-latest
|
|
9
|
-
steps:
|
|
10
|
-
- uses: actions/checkout@v3
|
|
11
|
-
name: Checkout
|
|
12
|
-
|
|
13
|
-
- uses: actions/setup-node@v4
|
|
14
|
-
name: Setup Node.js
|
|
15
|
-
with:
|
|
16
|
-
node-version: "22"
|
|
17
|
-
|
|
18
|
-
- run: npm ci
|
|
19
|
-
name: Install dependencies
|
|
20
|
-
|
|
21
|
-
- run: npm run build
|
|
22
|
-
name: Build project
|
|
23
|
-
|
|
24
|
-
- run: npx netlify-cli deploy --no-build --dir=dist --prod -s {{NETLIFY_SITE_ID}} --auth ${{ secrets.NETLIFY_AUTH_TOKEN }} --message "Deployed commit ${{ github.sha }}"
|
|
25
|
-
name: Deploy to Netlify
|
|
1
|
+
name: Build and Deploy to Netlify
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches:
|
|
5
|
+
- main
|
|
6
|
+
jobs:
|
|
7
|
+
build_and_deploy:
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
steps:
|
|
10
|
+
- uses: actions/checkout@v3
|
|
11
|
+
name: Checkout
|
|
12
|
+
|
|
13
|
+
- uses: actions/setup-node@v4
|
|
14
|
+
name: Setup Node.js
|
|
15
|
+
with:
|
|
16
|
+
node-version: "22"
|
|
17
|
+
|
|
18
|
+
- run: npm ci
|
|
19
|
+
name: Install dependencies
|
|
20
|
+
|
|
21
|
+
- run: npm run build
|
|
22
|
+
name: Build project
|
|
23
|
+
|
|
24
|
+
- run: npx netlify-cli deploy --no-build --dir=dist --prod -s {{NETLIFY_SITE_ID}} --auth ${{ secrets.NETLIFY_AUTH_TOKEN }} --message "Deployed commit ${{ github.sha }}"
|
|
25
|
+
name: Deploy to Netlify
|
|
@@ -4,6 +4,7 @@ import { dirname, join } from "node:path";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import chalk from "chalk";
|
|
6
6
|
import enquirer from "enquirer";
|
|
7
|
+
import { promptConfirm } from "../../shared/promptConfirm";
|
|
7
8
|
import { printDiff } from "../../utils/printDiff";
|
|
8
9
|
|
|
9
10
|
const WORKFLOW_PATH = ".github/workflows/build.yml";
|
|
@@ -44,12 +45,7 @@ async function updateWorkflow(siteId: string): Promise<void> {
|
|
|
44
45
|
console.log();
|
|
45
46
|
printDiff(oldContent, newContent);
|
|
46
47
|
|
|
47
|
-
const
|
|
48
|
-
type: "confirm",
|
|
49
|
-
name: "confirm",
|
|
50
|
-
message: chalk.red("Update build.yml?"),
|
|
51
|
-
initial: true,
|
|
52
|
-
});
|
|
48
|
+
const confirm = await promptConfirm(chalk.red("Update build.yml?"));
|
|
53
49
|
|
|
54
50
|
if (!confirm) {
|
|
55
51
|
console.log("Skipped build.yml update");
|
|
@@ -73,9 +69,33 @@ export async function init(): Promise<void> {
|
|
|
73
69
|
}
|
|
74
70
|
|
|
75
71
|
console.log("Creating Netlify site...\n");
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
72
|
+
try {
|
|
73
|
+
execSync("netlify sites:create --disable-linking", {
|
|
74
|
+
stdio: "inherit",
|
|
75
|
+
});
|
|
76
|
+
} catch (error) {
|
|
77
|
+
if (error instanceof Error && error.message.includes("command not found")) {
|
|
78
|
+
console.error(chalk.red("\nNetlify CLI is not installed.\n"));
|
|
79
|
+
const install = await promptConfirm("Would you like to install it now?");
|
|
80
|
+
if (install) {
|
|
81
|
+
console.log(chalk.dim("\nInstalling netlify-cli...\n"));
|
|
82
|
+
execSync("npm install -g netlify-cli", { stdio: "inherit" });
|
|
83
|
+
console.log();
|
|
84
|
+
execSync("netlify sites:create --disable-linking", {
|
|
85
|
+
stdio: "inherit",
|
|
86
|
+
});
|
|
87
|
+
} else {
|
|
88
|
+
console.log(
|
|
89
|
+
chalk.yellow(
|
|
90
|
+
"\nInstall it manually with: npm install -g netlify-cli\n",
|
|
91
|
+
),
|
|
92
|
+
);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
79
99
|
|
|
80
100
|
const { siteId } = await enquirer.prompt<{ siteId: string }>({
|
|
81
101
|
type: "input",
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
|
|
4
|
+
const TRAILING_SLASH_SCRIPT = ` <script>
|
|
5
|
+
if (!window.location.pathname.endsWith('/')) {
|
|
6
|
+
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
7
|
+
}
|
|
8
|
+
</script>`;
|
|
9
|
+
|
|
10
|
+
export function redirect(): void {
|
|
11
|
+
const indexPath = "index.html";
|
|
12
|
+
|
|
13
|
+
if (!existsSync(indexPath)) {
|
|
14
|
+
console.log(chalk.yellow("No index.html found"));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const content = readFileSync(indexPath, "utf-8");
|
|
19
|
+
|
|
20
|
+
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
21
|
+
console.log(chalk.dim("Trailing slash script already present"));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const headCloseIndex = content.indexOf("</head>");
|
|
26
|
+
if (headCloseIndex === -1) {
|
|
27
|
+
console.log(chalk.red("Could not find </head> tag in index.html"));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const newContent =
|
|
32
|
+
content.slice(0, headCloseIndex) +
|
|
33
|
+
TRAILING_SLASH_SCRIPT +
|
|
34
|
+
"\n " +
|
|
35
|
+
content.slice(headCloseIndex);
|
|
36
|
+
|
|
37
|
+
writeFileSync(indexPath, newContent);
|
|
38
|
+
console.log(chalk.green("Added trailing slash redirect to index.html"));
|
|
39
|
+
}
|
|
@@ -2,7 +2,7 @@ import * as fs from "node:fs";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import chalk from "chalk";
|
|
5
|
-
import
|
|
5
|
+
import { promptConfirm } from "../../shared/promptConfirm";
|
|
6
6
|
import { printDiff } from "../../utils/printDiff";
|
|
7
7
|
|
|
8
8
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -66,12 +66,7 @@ export async function enableRalph(): Promise<void> {
|
|
|
66
66
|
console.log();
|
|
67
67
|
printDiff(targetContent, mergedContent);
|
|
68
68
|
|
|
69
|
-
const
|
|
70
|
-
type: "confirm",
|
|
71
|
-
name: "confirm",
|
|
72
|
-
message: "Apply these changes?",
|
|
73
|
-
initial: true,
|
|
74
|
-
});
|
|
69
|
+
const confirm = await promptConfirm("Apply these changes?");
|
|
75
70
|
|
|
76
71
|
if (!confirm) {
|
|
77
72
|
console.log("Skipped");
|
|
@@ -3,12 +3,15 @@ import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import chalk from "chalk";
|
|
6
|
-
import
|
|
6
|
+
import { promptConfirm } from "../../shared/promptConfirm";
|
|
7
|
+
import { removeEslint } from "../../shared/removeEslint";
|
|
7
8
|
import { printDiff } from "../../utils/printDiff";
|
|
8
9
|
|
|
9
10
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
11
|
|
|
11
12
|
export async function init(): Promise<void> {
|
|
13
|
+
removeEslint();
|
|
14
|
+
|
|
12
15
|
const biomeConfigPath = "biome.json";
|
|
13
16
|
|
|
14
17
|
if (!existsSync(biomeConfigPath)) {
|
|
@@ -41,12 +44,7 @@ export async function init(): Promise<void> {
|
|
|
41
44
|
console.log();
|
|
42
45
|
printDiff(oldContent, newContent);
|
|
43
46
|
|
|
44
|
-
const
|
|
45
|
-
type: "confirm",
|
|
46
|
-
name: "confirm",
|
|
47
|
-
message: chalk.red("Update biome.json?"),
|
|
48
|
-
initial: true,
|
|
49
|
-
});
|
|
47
|
+
const confirm = await promptConfirm(chalk.red("Update biome.json?"));
|
|
50
48
|
|
|
51
49
|
if (!confirm) {
|
|
52
50
|
console.log("Skipped biome.json update");
|