@staff0rd/assist 0.209.1 → 0.210.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 +1 -0
- package/claude/commands/forward-comments.md +59 -0
- package/dist/index.js +120 -48
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -39,6 +39,7 @@ After installation, the `assist` command will be available globally. You can als
|
|
|
39
39
|
- `/commit` - Commit only relevant files from the session
|
|
40
40
|
- `/devlog` - Generate devlog entry for the next unversioned day
|
|
41
41
|
- `/draft` - Draft a new backlog item with LLM-assisted questioning
|
|
42
|
+
- `/forward-comments` - Split a coarse PR comment (e.g. from Slack) into per-line review comments on the current branch's PR, attributed to the original reviewer
|
|
42
43
|
- `/pr` - Raise a PR with a concise description
|
|
43
44
|
- `/refactor` - Run refactoring checks for code quality
|
|
44
45
|
- `/prompts` - Analyze denied tool calls and suggest settings changes to auto-allow recurring prompts
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Split a coarse PR comment (e.g. from Slack) into per-line review comments on the current branch's PR, attributed to the original reviewer
|
|
3
|
+
allowed_args: "<reviewer handle> — followed by the quoted comment text"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Take a multi-point comment that was given outside of GitHub's review UI (Slack, chat, in-person notes) and post each concern as a separate line-level review comment on the current branch's PR, attributed to the original reviewer with a `via @handle` prefix.
|
|
7
|
+
|
|
8
|
+
## Inputs
|
|
9
|
+
|
|
10
|
+
- **Reviewer handle** — the GitHub username of the person whose feedback this is (e.g. `Sebastian-MakerX`)
|
|
11
|
+
- **Comment text** — the verbatim feedback, usually pasted into the user's prompt
|
|
12
|
+
|
|
13
|
+
If either is missing or ambiguous, ask before proceeding. The PR is always the current branch's PR.
|
|
14
|
+
|
|
15
|
+
## Steps
|
|
16
|
+
|
|
17
|
+
1. **Split the comment into atomic concerns.** Each concern becomes one review comment. A concern is a single actionable point about a single location in the code. Framing prose ("the only thing slightly naff is..."), transitions ("Another thing is..."), and meta-comments ("looks pretty good") are NOT concerns — drop them.
|
|
18
|
+
|
|
19
|
+
2. **For each concern, locate the target file and line.** Read the PR's changed files (`gh pr diff` or `gh api repos/.../pulls/<n>/files`) and the relevant source. Anchor each comment on the most specific line that the concern is about:
|
|
20
|
+
- A suggestion about a specific resolver/function → the line of that resolver
|
|
21
|
+
- A suggestion about a file's name or location → line 1 of the file
|
|
22
|
+
- A suggestion about a type definition → the line where the type is defined
|
|
23
|
+
- A suggestion about a return shape → the line that constructs/returns it
|
|
24
|
+
|
|
25
|
+
3. **Compose each comment body.** Format:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
via @<handle>
|
|
29
|
+
|
|
30
|
+
> <verbatim quote of just the part relevant to this line>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Rules for the quote:
|
|
34
|
+
- **Quote verbatim.** Preserve the reviewer's exact wording, including typos, repeated words, odd spacing, and punctuation. Do not paraphrase, "fix," or tidy. The reviewer's voice matters.
|
|
35
|
+
- **Drop framing prose.** Only the actionable suggestion that maps to *this specific line* should appear. If the reviewer's sentence opens with broad framing ("the only thing that's slightly naff is...") and then states the suggestion, quote only the suggestion part.
|
|
36
|
+
- **Add backticks around symbols.** Identifier names, type names, file names, and function names should be wrapped in backticks (e.g. `` `displayValue` ``, `` `SurveyQuestionModel` ``, `` `resolvers.ts` ``) even if the reviewer didn't use them. This is the only formatting change permitted.
|
|
37
|
+
- **No editorialising.** Do not add your own commentary, explanation, or restatement. The whole body is the attribution line plus the quote.
|
|
38
|
+
|
|
39
|
+
4. **Confirm placements before posting.** List each planned comment to the user as `<file>:<line> — <one-line summary>`. Wait for the user to confirm or correct file/line choices.
|
|
40
|
+
|
|
41
|
+
5. **Post each comment** via:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
assist prs comment '<path>' <line> '<body>' 2>&1
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- Always single-quote `<path>` and `<body>`. Never double-quote — backticks in the body would break.
|
|
48
|
+
- For apostrophes inside the body (e.g. `it's`), use the shell escape `'\''`.
|
|
49
|
+
- Bodies must not contain "claude" or "opus" (the command rejects them).
|
|
50
|
+
- Run posts in parallel when there are no dependencies between them.
|
|
51
|
+
|
|
52
|
+
6. **Report** the resulting `<file>:<line>` line returned by each `assist prs comment` call, plus any failures.
|
|
53
|
+
|
|
54
|
+
## Notes
|
|
55
|
+
|
|
56
|
+
- `assist prs comment` publishes a new review thread immediately (despite the help text saying "pending review") — the comment appears live and notifies subscribers.
|
|
57
|
+
- `assist prs comment` targets the **current branch's PR**. If the feedback is for a different PR, switch branches first.
|
|
58
|
+
- If the same concern legitimately spans multiple lines/files, post one comment per anchor location, not a single combined comment.
|
|
59
|
+
- If the reviewer's text contains a clear typo of a real symbol name (e.g. `SuveyQuestion` for `SurveyQuestion`), preserve the typo in the quote. Do not silently correct.
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.210.1",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -8915,7 +8915,68 @@ import { tmpdir as tmpdir4 } from "os";
|
|
|
8915
8915
|
import { join as join29 } from "path";
|
|
8916
8916
|
|
|
8917
8917
|
// src/commands/prs/shared.ts
|
|
8918
|
+
import { execSync as execSync27 } from "child_process";
|
|
8919
|
+
|
|
8920
|
+
// src/commands/prs/getPreferredRemoteRepo.ts
|
|
8918
8921
|
import { execSync as execSync26 } from "child_process";
|
|
8922
|
+
var GITHUB_URL_PATTERN = /(?:git@github\.com:|https:\/\/github\.com\/)([^/]+)\/([^/]+?)(?:\.git)?\/?$/;
|
|
8923
|
+
function parseGitHubUrl(url) {
|
|
8924
|
+
const match = url.match(GITHUB_URL_PATTERN);
|
|
8925
|
+
if (!match) return null;
|
|
8926
|
+
return { org: match[1], repo: match[2] };
|
|
8927
|
+
}
|
|
8928
|
+
function tryGetRemoteUrl(remote) {
|
|
8929
|
+
try {
|
|
8930
|
+
return execSync26(`git remote get-url ${remote}`, {
|
|
8931
|
+
encoding: "utf-8",
|
|
8932
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
8933
|
+
}).trim();
|
|
8934
|
+
} catch {
|
|
8935
|
+
return null;
|
|
8936
|
+
}
|
|
8937
|
+
}
|
|
8938
|
+
function getCurrentBranchRemote() {
|
|
8939
|
+
try {
|
|
8940
|
+
const ref = execSync26(
|
|
8941
|
+
"git rev-parse --abbrev-ref --symbolic-full-name @{u}",
|
|
8942
|
+
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
8943
|
+
).trim();
|
|
8944
|
+
const [remote] = ref.split("/", 1);
|
|
8945
|
+
return remote || null;
|
|
8946
|
+
} catch {
|
|
8947
|
+
return null;
|
|
8948
|
+
}
|
|
8949
|
+
}
|
|
8950
|
+
function listRemotes() {
|
|
8951
|
+
try {
|
|
8952
|
+
return execSync26("git remote", {
|
|
8953
|
+
encoding: "utf-8",
|
|
8954
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
8955
|
+
}).trim().split("\n").filter(Boolean);
|
|
8956
|
+
} catch {
|
|
8957
|
+
return [];
|
|
8958
|
+
}
|
|
8959
|
+
}
|
|
8960
|
+
function getPreferredRemoteRepo() {
|
|
8961
|
+
const candidates = [];
|
|
8962
|
+
const tracked = getCurrentBranchRemote();
|
|
8963
|
+
if (tracked) candidates.push(tracked);
|
|
8964
|
+
if (!candidates.includes("origin")) candidates.push("origin");
|
|
8965
|
+
for (const remote of listRemotes()) {
|
|
8966
|
+
if (remote !== "upstream" && !candidates.includes(remote)) {
|
|
8967
|
+
candidates.push(remote);
|
|
8968
|
+
}
|
|
8969
|
+
}
|
|
8970
|
+
for (const remote of candidates) {
|
|
8971
|
+
const url = tryGetRemoteUrl(remote);
|
|
8972
|
+
if (!url) continue;
|
|
8973
|
+
const parsed = parseGitHubUrl(url);
|
|
8974
|
+
if (parsed) return parsed;
|
|
8975
|
+
}
|
|
8976
|
+
return null;
|
|
8977
|
+
}
|
|
8978
|
+
|
|
8979
|
+
// src/commands/prs/shared.ts
|
|
8919
8980
|
function isGhNotInstalled(error) {
|
|
8920
8981
|
if (error instanceof Error) {
|
|
8921
8982
|
const msg = error.message.toLowerCase();
|
|
@@ -8930,17 +8991,30 @@ function isNotFound(error) {
|
|
|
8930
8991
|
return false;
|
|
8931
8992
|
}
|
|
8932
8993
|
function getRepoInfo() {
|
|
8994
|
+
const preferred = getPreferredRemoteRepo();
|
|
8995
|
+
if (preferred) return preferred;
|
|
8933
8996
|
const repoInfo = JSON.parse(
|
|
8934
|
-
|
|
8997
|
+
execSync27("gh repo view --json owner,name", { encoding: "utf-8" })
|
|
8935
8998
|
);
|
|
8936
8999
|
return { org: repoInfo.owner.login, repo: repoInfo.name };
|
|
8937
9000
|
}
|
|
9001
|
+
function getCurrentBranch() {
|
|
9002
|
+
return execSync27("git rev-parse --abbrev-ref HEAD", {
|
|
9003
|
+
encoding: "utf-8"
|
|
9004
|
+
}).trim();
|
|
9005
|
+
}
|
|
9006
|
+
function viewCurrentPr(fields) {
|
|
9007
|
+
const { org, repo } = getRepoInfo();
|
|
9008
|
+
const branch = getCurrentBranch();
|
|
9009
|
+
return JSON.parse(
|
|
9010
|
+
execSync27(`gh pr view ${branch} --json ${fields} -R ${org}/${repo}`, {
|
|
9011
|
+
encoding: "utf-8"
|
|
9012
|
+
})
|
|
9013
|
+
);
|
|
9014
|
+
}
|
|
8938
9015
|
function getCurrentPrNumber() {
|
|
8939
9016
|
try {
|
|
8940
|
-
|
|
8941
|
-
execSync26("gh pr view --json number", { encoding: "utf-8" })
|
|
8942
|
-
);
|
|
8943
|
-
return prInfo.number;
|
|
9017
|
+
return viewCurrentPr("number").number;
|
|
8944
9018
|
} catch (error) {
|
|
8945
9019
|
if (error instanceof Error && error.message.includes("no pull requests")) {
|
|
8946
9020
|
console.error("Error: No pull request found for the current branch.");
|
|
@@ -8951,10 +9025,7 @@ function getCurrentPrNumber() {
|
|
|
8951
9025
|
}
|
|
8952
9026
|
function getCurrentPrNodeId() {
|
|
8953
9027
|
try {
|
|
8954
|
-
|
|
8955
|
-
execSync26("gh pr view --json id", { encoding: "utf-8" })
|
|
8956
|
-
);
|
|
8957
|
-
return prInfo.id;
|
|
9028
|
+
return viewCurrentPr("id").id;
|
|
8958
9029
|
} catch (error) {
|
|
8959
9030
|
if (error instanceof Error && error.message.includes("no pull requests")) {
|
|
8960
9031
|
console.error("Error: No pull request found for the current branch.");
|
|
@@ -9023,10 +9094,10 @@ function comment2(path53, line, body) {
|
|
|
9023
9094
|
}
|
|
9024
9095
|
|
|
9025
9096
|
// src/commands/prs/fixed.ts
|
|
9026
|
-
import { execSync as
|
|
9097
|
+
import { execSync as execSync29 } from "child_process";
|
|
9027
9098
|
|
|
9028
9099
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
9029
|
-
import { execSync as
|
|
9100
|
+
import { execSync as execSync28 } from "child_process";
|
|
9030
9101
|
import { unlinkSync as unlinkSync8, writeFileSync as writeFileSync23 } from "fs";
|
|
9031
9102
|
import { tmpdir as tmpdir5 } from "os";
|
|
9032
9103
|
import { join as join31 } from "path";
|
|
@@ -9056,7 +9127,7 @@ function deleteCommentsCache(prNumber) {
|
|
|
9056
9127
|
|
|
9057
9128
|
// src/commands/prs/resolveCommentWithReply.ts
|
|
9058
9129
|
function replyToComment(org, repo, prNumber, commentId, message) {
|
|
9059
|
-
|
|
9130
|
+
execSync28(
|
|
9060
9131
|
`gh api repos/${org}/${repo}/pulls/${prNumber}/comments -f body="${message.replace(/"/g, '\\"')}" -F in_reply_to=${commentId}`,
|
|
9061
9132
|
{ stdio: ["inherit", "pipe", "inherit"] }
|
|
9062
9133
|
);
|
|
@@ -9066,7 +9137,7 @@ function resolveThread(threadId) {
|
|
|
9066
9137
|
const queryFile = join31(tmpdir5(), `gh-mutation-${Date.now()}.graphql`);
|
|
9067
9138
|
writeFileSync23(queryFile, mutation);
|
|
9068
9139
|
try {
|
|
9069
|
-
|
|
9140
|
+
execSync28(
|
|
9070
9141
|
`gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
|
|
9071
9142
|
{ stdio: ["inherit", "pipe", "inherit"] }
|
|
9072
9143
|
);
|
|
@@ -9118,7 +9189,7 @@ function resolveCommentWithReply(commentId, message) {
|
|
|
9118
9189
|
// src/commands/prs/fixed.ts
|
|
9119
9190
|
function verifySha(sha) {
|
|
9120
9191
|
try {
|
|
9121
|
-
return
|
|
9192
|
+
return execSync29(`git rev-parse --verify ${sha}`, {
|
|
9122
9193
|
encoding: "utf-8"
|
|
9123
9194
|
}).trim();
|
|
9124
9195
|
} catch {
|
|
@@ -9132,7 +9203,7 @@ function fixed(commentId, sha) {
|
|
|
9132
9203
|
const { org, repo } = getRepoInfo();
|
|
9133
9204
|
const repoUrl = `https://github.com/${org}/${repo}`;
|
|
9134
9205
|
const message = `Fixed in [${fullSha}](${repoUrl}/commit/${fullSha})`;
|
|
9135
|
-
|
|
9206
|
+
execSync29("git push", { stdio: "inherit" });
|
|
9136
9207
|
resolveCommentWithReply(commentId, message);
|
|
9137
9208
|
} catch (error) {
|
|
9138
9209
|
if (isGhNotInstalled(error)) {
|
|
@@ -9150,7 +9221,7 @@ import { join as join33 } from "path";
|
|
|
9150
9221
|
import { stringify } from "yaml";
|
|
9151
9222
|
|
|
9152
9223
|
// src/commands/prs/fetchThreadIds.ts
|
|
9153
|
-
import { execSync as
|
|
9224
|
+
import { execSync as execSync30 } from "child_process";
|
|
9154
9225
|
import { unlinkSync as unlinkSync9, writeFileSync as writeFileSync24 } from "fs";
|
|
9155
9226
|
import { tmpdir as tmpdir6 } from "os";
|
|
9156
9227
|
import { join as join32 } from "path";
|
|
@@ -9159,7 +9230,7 @@ function fetchThreadIds(org, repo, prNumber) {
|
|
|
9159
9230
|
const queryFile = join32(tmpdir6(), `gh-query-${Date.now()}.graphql`);
|
|
9160
9231
|
writeFileSync24(queryFile, THREAD_QUERY);
|
|
9161
9232
|
try {
|
|
9162
|
-
const result =
|
|
9233
|
+
const result = execSync30(
|
|
9163
9234
|
`gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
|
|
9164
9235
|
{ encoding: "utf-8" }
|
|
9165
9236
|
);
|
|
@@ -9181,9 +9252,9 @@ function fetchThreadIds(org, repo, prNumber) {
|
|
|
9181
9252
|
}
|
|
9182
9253
|
|
|
9183
9254
|
// src/commands/prs/listComments/fetchReviewComments.ts
|
|
9184
|
-
import { execSync as
|
|
9255
|
+
import { execSync as execSync31 } from "child_process";
|
|
9185
9256
|
function fetchJson(endpoint) {
|
|
9186
|
-
const result =
|
|
9257
|
+
const result = execSync31(`gh api --paginate ${endpoint}`, {
|
|
9187
9258
|
encoding: "utf-8"
|
|
9188
9259
|
});
|
|
9189
9260
|
if (!result.trim()) return [];
|
|
@@ -9322,7 +9393,7 @@ async function listComments() {
|
|
|
9322
9393
|
}
|
|
9323
9394
|
|
|
9324
9395
|
// src/commands/prs/prs/index.ts
|
|
9325
|
-
import { execSync as
|
|
9396
|
+
import { execSync as execSync32 } from "child_process";
|
|
9326
9397
|
|
|
9327
9398
|
// src/commands/prs/prs/displayPaginated/index.ts
|
|
9328
9399
|
import enquirer9 from "enquirer";
|
|
@@ -9428,8 +9499,9 @@ async function displayPaginated(pullRequests) {
|
|
|
9428
9499
|
async function prs(options2) {
|
|
9429
9500
|
const state = options2.open ? "open" : options2.closed ? "closed" : "all";
|
|
9430
9501
|
try {
|
|
9431
|
-
const
|
|
9432
|
-
|
|
9502
|
+
const { org, repo } = getRepoInfo();
|
|
9503
|
+
const result = execSync32(
|
|
9504
|
+
`gh pr list --state ${state} --json number,title,url,author,createdAt,mergedAt,closedAt,state,changedFiles --limit 100 -R ${org}/${repo}`,
|
|
9433
9505
|
{ encoding: "utf-8" }
|
|
9434
9506
|
);
|
|
9435
9507
|
const pullRequests = JSON.parse(result);
|
|
@@ -9451,7 +9523,7 @@ async function prs(options2) {
|
|
|
9451
9523
|
}
|
|
9452
9524
|
|
|
9453
9525
|
// src/commands/prs/wontfix.ts
|
|
9454
|
-
import { execSync as
|
|
9526
|
+
import { execSync as execSync33 } from "child_process";
|
|
9455
9527
|
function validateReason(reason) {
|
|
9456
9528
|
const lowerReason = reason.toLowerCase();
|
|
9457
9529
|
if (lowerReason.includes("claude") || lowerReason.includes("opus")) {
|
|
@@ -9468,7 +9540,7 @@ function validateShaReferences(reason) {
|
|
|
9468
9540
|
const invalidShas = [];
|
|
9469
9541
|
for (const sha of shas) {
|
|
9470
9542
|
try {
|
|
9471
|
-
|
|
9543
|
+
execSync33(`git cat-file -t ${sha}`, { stdio: "pipe" });
|
|
9472
9544
|
} catch {
|
|
9473
9545
|
invalidShas.push(sha);
|
|
9474
9546
|
}
|
|
@@ -9582,10 +9654,10 @@ import chalk107 from "chalk";
|
|
|
9582
9654
|
import Enquirer2 from "enquirer";
|
|
9583
9655
|
|
|
9584
9656
|
// src/commands/ravendb/searchItems.ts
|
|
9585
|
-
import { execSync as
|
|
9657
|
+
import { execSync as execSync34 } from "child_process";
|
|
9586
9658
|
import chalk106 from "chalk";
|
|
9587
9659
|
function opExec(args) {
|
|
9588
|
-
return
|
|
9660
|
+
return execSync34(`op ${args}`, {
|
|
9589
9661
|
encoding: "utf-8",
|
|
9590
9662
|
stdio: ["pipe", "pipe", "pipe"]
|
|
9591
9663
|
}).trim();
|
|
@@ -9737,7 +9809,7 @@ ${errorText}`
|
|
|
9737
9809
|
}
|
|
9738
9810
|
|
|
9739
9811
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
9740
|
-
import { execSync as
|
|
9812
|
+
import { execSync as execSync35 } from "child_process";
|
|
9741
9813
|
import chalk111 from "chalk";
|
|
9742
9814
|
function resolveOpSecret(reference) {
|
|
9743
9815
|
if (!reference.startsWith("op://")) {
|
|
@@ -9745,7 +9817,7 @@ function resolveOpSecret(reference) {
|
|
|
9745
9817
|
process.exit(1);
|
|
9746
9818
|
}
|
|
9747
9819
|
try {
|
|
9748
|
-
return
|
|
9820
|
+
return execSync35(`op read "${reference}"`, {
|
|
9749
9821
|
encoding: "utf-8",
|
|
9750
9822
|
stdio: ["pipe", "pipe", "pipe"]
|
|
9751
9823
|
}).trim();
|
|
@@ -9994,7 +10066,7 @@ Refactor check failed:
|
|
|
9994
10066
|
}
|
|
9995
10067
|
|
|
9996
10068
|
// src/commands/refactor/check/getViolations/index.ts
|
|
9997
|
-
import { execSync as
|
|
10069
|
+
import { execSync as execSync36 } from "child_process";
|
|
9998
10070
|
import fs18 from "fs";
|
|
9999
10071
|
import { minimatch as minimatch4 } from "minimatch";
|
|
10000
10072
|
|
|
@@ -10044,7 +10116,7 @@ function getGitFiles(options2) {
|
|
|
10044
10116
|
}
|
|
10045
10117
|
const files = /* @__PURE__ */ new Set();
|
|
10046
10118
|
if (options2.staged || options2.modified) {
|
|
10047
|
-
const staged =
|
|
10119
|
+
const staged = execSync36("git diff --cached --name-only", {
|
|
10048
10120
|
encoding: "utf-8"
|
|
10049
10121
|
});
|
|
10050
10122
|
for (const file of staged.trim().split("\n").filter(Boolean)) {
|
|
@@ -10052,7 +10124,7 @@ function getGitFiles(options2) {
|
|
|
10052
10124
|
}
|
|
10053
10125
|
}
|
|
10054
10126
|
if (options2.unstaged || options2.modified) {
|
|
10055
|
-
const unstaged =
|
|
10127
|
+
const unstaged = execSync36("git diff --name-only", { encoding: "utf-8" });
|
|
10056
10128
|
for (const file of unstaged.trim().split("\n").filter(Boolean)) {
|
|
10057
10129
|
files.add(file);
|
|
10058
10130
|
}
|
|
@@ -12777,7 +12849,7 @@ import { mkdirSync as mkdirSync13 } from "fs";
|
|
|
12777
12849
|
import { join as join43 } from "path";
|
|
12778
12850
|
|
|
12779
12851
|
// src/commands/voice/checkLockFile.ts
|
|
12780
|
-
import { execSync as
|
|
12852
|
+
import { execSync as execSync37 } from "child_process";
|
|
12781
12853
|
import { existsSync as existsSync38, mkdirSync as mkdirSync12, readFileSync as readFileSync32, writeFileSync as writeFileSync27 } from "fs";
|
|
12782
12854
|
import { join as join42 } from "path";
|
|
12783
12855
|
function isProcessAlive2(pid) {
|
|
@@ -12806,7 +12878,7 @@ function bootstrapVenv() {
|
|
|
12806
12878
|
if (existsSync38(getVenvPython())) return;
|
|
12807
12879
|
console.log("Setting up Python environment...");
|
|
12808
12880
|
const pythonDir = getPythonDir();
|
|
12809
|
-
|
|
12881
|
+
execSync37(
|
|
12810
12882
|
`uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
|
|
12811
12883
|
{
|
|
12812
12884
|
stdio: "inherit",
|
|
@@ -12973,11 +13045,11 @@ import { randomBytes } from "crypto";
|
|
|
12973
13045
|
import chalk140 from "chalk";
|
|
12974
13046
|
|
|
12975
13047
|
// src/lib/openBrowser.ts
|
|
12976
|
-
import { execSync as
|
|
13048
|
+
import { execSync as execSync38 } from "child_process";
|
|
12977
13049
|
function tryExec(commands) {
|
|
12978
13050
|
for (const cmd of commands) {
|
|
12979
13051
|
try {
|
|
12980
|
-
|
|
13052
|
+
execSync38(cmd);
|
|
12981
13053
|
return true;
|
|
12982
13054
|
} catch {
|
|
12983
13055
|
}
|
|
@@ -13319,11 +13391,11 @@ function resolveParams(params, cliArgs) {
|
|
|
13319
13391
|
}
|
|
13320
13392
|
|
|
13321
13393
|
// src/commands/run/runPreCommands.ts
|
|
13322
|
-
import { execSync as
|
|
13394
|
+
import { execSync as execSync39 } from "child_process";
|
|
13323
13395
|
function runPreCommands(pre, cwd) {
|
|
13324
13396
|
for (const cmd of pre) {
|
|
13325
13397
|
try {
|
|
13326
|
-
|
|
13398
|
+
execSync39(cmd, { stdio: "inherit", cwd });
|
|
13327
13399
|
} catch (err) {
|
|
13328
13400
|
const code = err && typeof err === "object" && "status" in err ? err.status : 1;
|
|
13329
13401
|
process.exit(code);
|
|
@@ -13576,7 +13648,7 @@ function registerRun(program2) {
|
|
|
13576
13648
|
}
|
|
13577
13649
|
|
|
13578
13650
|
// src/commands/screenshot/index.ts
|
|
13579
|
-
import { execSync as
|
|
13651
|
+
import { execSync as execSync40 } from "child_process";
|
|
13580
13652
|
import { existsSync as existsSync43, mkdirSync as mkdirSync16, unlinkSync as unlinkSync12, writeFileSync as writeFileSync30 } from "fs";
|
|
13581
13653
|
import { tmpdir as tmpdir7 } from "os";
|
|
13582
13654
|
import { join as join49, resolve as resolve13 } from "path";
|
|
@@ -13719,7 +13791,7 @@ function runPowerShellScript(processName, outputPath) {
|
|
|
13719
13791
|
const scriptPath = join49(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
|
|
13720
13792
|
writeFileSync30(scriptPath, captureWindowPs1, "utf-8");
|
|
13721
13793
|
try {
|
|
13722
|
-
|
|
13794
|
+
execSync40(
|
|
13723
13795
|
`powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
|
|
13724
13796
|
{ stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }
|
|
13725
13797
|
);
|
|
@@ -14120,7 +14192,7 @@ function syncCommands(claudeDir, targetBase) {
|
|
|
14120
14192
|
}
|
|
14121
14193
|
|
|
14122
14194
|
// src/commands/update.ts
|
|
14123
|
-
import { execSync as
|
|
14195
|
+
import { execSync as execSync41 } from "child_process";
|
|
14124
14196
|
import * as path52 from "path";
|
|
14125
14197
|
function isGlobalNpmInstall(dir) {
|
|
14126
14198
|
try {
|
|
@@ -14128,7 +14200,7 @@ function isGlobalNpmInstall(dir) {
|
|
|
14128
14200
|
if (resolved.split(path52.sep).includes("node_modules")) {
|
|
14129
14201
|
return true;
|
|
14130
14202
|
}
|
|
14131
|
-
const globalPrefix =
|
|
14203
|
+
const globalPrefix = execSync41("npm prefix -g", { stdio: "pipe" }).toString().trim();
|
|
14132
14204
|
return resolved.toLowerCase().startsWith(path52.resolve(globalPrefix).toLowerCase());
|
|
14133
14205
|
} catch {
|
|
14134
14206
|
return false;
|
|
@@ -14139,18 +14211,18 @@ async function update2() {
|
|
|
14139
14211
|
console.log(`Assist is installed at: ${installDir}`);
|
|
14140
14212
|
if (isGitRepo(installDir)) {
|
|
14141
14213
|
console.log("Detected git repo installation, pulling latest...");
|
|
14142
|
-
|
|
14214
|
+
execSync41("git pull", { cwd: installDir, stdio: "inherit" });
|
|
14143
14215
|
console.log("Installing dependencies...");
|
|
14144
|
-
|
|
14216
|
+
execSync41("npm i", { cwd: installDir, stdio: "inherit" });
|
|
14145
14217
|
console.log("Building...");
|
|
14146
|
-
|
|
14218
|
+
execSync41("npm run build", { cwd: installDir, stdio: "inherit" });
|
|
14147
14219
|
console.log("Syncing commands...");
|
|
14148
|
-
|
|
14220
|
+
execSync41("assist sync", { stdio: "inherit" });
|
|
14149
14221
|
} else if (isGlobalNpmInstall(installDir)) {
|
|
14150
14222
|
console.log("Detected global npm installation, updating...");
|
|
14151
|
-
|
|
14223
|
+
execSync41("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
|
|
14152
14224
|
console.log("Syncing commands...");
|
|
14153
|
-
|
|
14225
|
+
execSync41("assist sync", { stdio: "inherit" });
|
|
14154
14226
|
} else {
|
|
14155
14227
|
console.error(
|
|
14156
14228
|
"Could not determine installation method. Expected a git repo or global npm install."
|