@synkro-sh/cli 1.0.2 → 1.0.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/bootstrap.js +167 -109
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -133,6 +133,16 @@ function installCCHooks(settingsPath, config) {
|
|
|
133
133
|
],
|
|
134
134
|
[SYNKRO_MARKER]: true
|
|
135
135
|
});
|
|
136
|
+
settings.hooks.PostToolUse.push({
|
|
137
|
+
matcher: "Bash",
|
|
138
|
+
hooks: [
|
|
139
|
+
{
|
|
140
|
+
type: "command",
|
|
141
|
+
command: config.bashFollowupScriptPath
|
|
142
|
+
}
|
|
143
|
+
],
|
|
144
|
+
[SYNKRO_MARKER]: true
|
|
145
|
+
});
|
|
136
146
|
settings.hooks.SessionEnd.push({
|
|
137
147
|
hooks: [
|
|
138
148
|
{
|
|
@@ -274,7 +284,7 @@ var init_mcpConfig = __esm({
|
|
|
274
284
|
});
|
|
275
285
|
|
|
276
286
|
// cli/installer/hookScripts.ts
|
|
277
|
-
var CC_BASH_JUDGE_SCRIPT, CC_EDIT_PRECHECK_SCRIPT, CC_EDIT_CAPTURE_SCRIPT, CC_STOP_SUMMARY_SCRIPT, CC_SESSION_START_SCRIPT;
|
|
287
|
+
var CC_BASH_JUDGE_SCRIPT, CC_EDIT_PRECHECK_SCRIPT, CC_EDIT_CAPTURE_SCRIPT, CC_STOP_SUMMARY_SCRIPT, CC_SESSION_START_SCRIPT, CC_BASH_FOLLOWUP_SCRIPT;
|
|
278
288
|
var init_hookScripts = __esm({
|
|
279
289
|
"cli/installer/hookScripts.ts"() {
|
|
280
290
|
"use strict";
|
|
@@ -1183,6 +1193,48 @@ fi
|
|
|
1183
1193
|
|
|
1184
1194
|
jq -n --arg sys_msg "$SYS_MSG" '{ systemMessage: $sys_msg }'
|
|
1185
1195
|
exit 0
|
|
1196
|
+
`;
|
|
1197
|
+
CC_BASH_FOLLOWUP_SCRIPT = `#!/bin/bash
|
|
1198
|
+
# Synkro PostToolUse Bash hook \u2014 minimal correction-followup fire.
|
|
1199
|
+
# No grading happens here; verdict already came from PreToolUse. This is just
|
|
1200
|
+
# the "user approved + agent ran it" capture.
|
|
1201
|
+
set -e
|
|
1202
|
+
|
|
1203
|
+
CONFIG_FILE="$HOME/.synkro/config.env"
|
|
1204
|
+
if [ -f "$CONFIG_FILE" ]; then
|
|
1205
|
+
set -a
|
|
1206
|
+
# shellcheck disable=SC1090
|
|
1207
|
+
. "$CONFIG_FILE"
|
|
1208
|
+
set +a
|
|
1209
|
+
fi
|
|
1210
|
+
|
|
1211
|
+
GATEWAY_URL="\${SYNKRO_GATEWAY_URL:-https://api.synkro.sh}"
|
|
1212
|
+
CREDS_PATH="\${SYNKRO_CREDENTIALS_PATH:-$HOME/.synkro/credentials.json}"
|
|
1213
|
+
|
|
1214
|
+
if [ ! -f "$CREDS_PATH" ]; then echo '{}'; exit 0; fi
|
|
1215
|
+
JWT=$(jq -r '.access_token // empty' "$CREDS_PATH" 2>/dev/null)
|
|
1216
|
+
if [ -z "$JWT" ]; then echo '{}'; exit 0; fi
|
|
1217
|
+
|
|
1218
|
+
PAYLOAD=$(cat)
|
|
1219
|
+
TOOL_NAME=$(echo "$PAYLOAD" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
1220
|
+
if [ "$TOOL_NAME" != "Bash" ]; then echo '{}'; exit 0; fi
|
|
1221
|
+
|
|
1222
|
+
SESSION_ID=$(echo "$PAYLOAD" | jq -r '.session_id // empty' 2>/dev/null)
|
|
1223
|
+
TOOL_USE_ID=$(echo "$PAYLOAD" | jq -r '.tool_use_id // empty' 2>/dev/null)
|
|
1224
|
+
if [ -z "$SESSION_ID" ] || [ -z "$TOOL_USE_ID" ]; then echo '{}'; exit 0; fi
|
|
1225
|
+
|
|
1226
|
+
BODY=$(jq -n --arg sid "$SESSION_ID" --arg tid "$TOOL_USE_ID" \\
|
|
1227
|
+
'{session_id: $sid, tool_use_id: $tid, decision: "allow"}')
|
|
1228
|
+
|
|
1229
|
+
curl -sS -X POST "\${GATEWAY_URL}/api/v1/precheck-edit/correction-followup" \\
|
|
1230
|
+
-H "Content-Type: application/json" \\
|
|
1231
|
+
-H "Authorization: Bearer $JWT" \\
|
|
1232
|
+
-d "$BODY" \\
|
|
1233
|
+
--max-time 2 \\
|
|
1234
|
+
>/dev/null 2>&1 || true
|
|
1235
|
+
|
|
1236
|
+
echo '{}'
|
|
1237
|
+
exit 0
|
|
1186
1238
|
`;
|
|
1187
1239
|
}
|
|
1188
1240
|
});
|
|
@@ -1543,22 +1595,26 @@ import { createServer } from "http";
|
|
|
1543
1595
|
import { writeFileSync as writeFileSync3, readFileSync as readFileSync3, existsSync as existsSync4, mkdirSync as mkdirSync3, unlinkSync as unlinkSync2 } from "fs";
|
|
1544
1596
|
import { homedir as homedir3, platform } from "os";
|
|
1545
1597
|
import { join as join3, dirname as dirname3 } from "path";
|
|
1546
|
-
import {
|
|
1598
|
+
import { execFile } from "child_process";
|
|
1547
1599
|
import jwt from "jsonwebtoken";
|
|
1548
1600
|
function openBrowser(url) {
|
|
1549
1601
|
const os = platform();
|
|
1550
|
-
let
|
|
1602
|
+
let bin;
|
|
1603
|
+
let args2;
|
|
1551
1604
|
switch (os) {
|
|
1552
1605
|
case "darwin":
|
|
1553
|
-
|
|
1606
|
+
bin = "open";
|
|
1607
|
+
args2 = [url];
|
|
1554
1608
|
break;
|
|
1555
1609
|
case "win32":
|
|
1556
|
-
|
|
1610
|
+
bin = "cmd";
|
|
1611
|
+
args2 = ["/c", "start", "", url];
|
|
1557
1612
|
break;
|
|
1558
1613
|
default:
|
|
1559
|
-
|
|
1614
|
+
bin = "xdg-open";
|
|
1615
|
+
args2 = [url];
|
|
1560
1616
|
}
|
|
1561
|
-
|
|
1617
|
+
execFile(bin, args2, (error) => {
|
|
1562
1618
|
if (error) {
|
|
1563
1619
|
console.error("Failed to open browser automatically.");
|
|
1564
1620
|
console.log(`Please open this URL manually: ${url}`);
|
|
@@ -1585,14 +1641,30 @@ function loadCredentials() {
|
|
|
1585
1641
|
}
|
|
1586
1642
|
function createCallbackServer() {
|
|
1587
1643
|
const CORS_HEADERS = {
|
|
1588
|
-
"Access-Control-Allow-Origin":
|
|
1589
|
-
"Access-Control-Allow-Methods": "
|
|
1590
|
-
"Access-Control-Allow-Headers": "
|
|
1644
|
+
"Access-Control-Allow-Origin": SYNKRO_WEB_AUTH_URL,
|
|
1645
|
+
"Access-Control-Allow-Methods": "POST, OPTIONS",
|
|
1646
|
+
"Access-Control-Allow-Headers": "Content-Type",
|
|
1647
|
+
"Vary": "Origin"
|
|
1591
1648
|
};
|
|
1592
1649
|
return new Promise((resolve2, reject) => {
|
|
1593
1650
|
const server = createServer((req, res) => {
|
|
1594
1651
|
if (req.method === "OPTIONS") {
|
|
1595
|
-
|
|
1652
|
+
const origin = req.headers.origin;
|
|
1653
|
+
if (origin === SYNKRO_WEB_AUTH_URL) {
|
|
1654
|
+
res.writeHead(204, CORS_HEADERS);
|
|
1655
|
+
} else {
|
|
1656
|
+
res.writeHead(204, {
|
|
1657
|
+
"Access-Control-Allow-Methods": "POST, OPTIONS",
|
|
1658
|
+
"Access-Control-Allow-Headers": "Content-Type",
|
|
1659
|
+
"Vary": "Origin"
|
|
1660
|
+
});
|
|
1661
|
+
}
|
|
1662
|
+
res.end();
|
|
1663
|
+
return;
|
|
1664
|
+
}
|
|
1665
|
+
const reqOrigin = req.headers.origin;
|
|
1666
|
+
if (reqOrigin && reqOrigin !== SYNKRO_WEB_AUTH_URL) {
|
|
1667
|
+
res.writeHead(403, { "Vary": "Origin" });
|
|
1596
1668
|
res.end();
|
|
1597
1669
|
return;
|
|
1598
1670
|
}
|
|
@@ -1607,35 +1679,78 @@ function createCallbackServer() {
|
|
|
1607
1679
|
res.end();
|
|
1608
1680
|
return;
|
|
1609
1681
|
}
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
const userId = url.searchParams.get("user_id") || "";
|
|
1613
|
-
const email = url.searchParams.get("email") || "";
|
|
1614
|
-
const orgId = url.searchParams.get("org_id") || "";
|
|
1615
|
-
const state = url.searchParams.get("state") || "";
|
|
1616
|
-
if (!token) {
|
|
1617
|
-
res.writeHead(400, { ...CORS_HEADERS, "Content-Type": "text/html" });
|
|
1682
|
+
if (req.method !== "POST") {
|
|
1683
|
+
res.writeHead(405, { ...CORS_HEADERS, "Allow": "POST, OPTIONS", "Content-Type": "text/html" });
|
|
1618
1684
|
res.end(ERROR_HTML);
|
|
1619
|
-
setTimeout(() => {
|
|
1620
|
-
server.close();
|
|
1621
|
-
reject(new Error("Authentication failed: missing token in callback"));
|
|
1622
|
-
}, 500);
|
|
1623
1685
|
return;
|
|
1624
1686
|
}
|
|
1625
|
-
const
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1687
|
+
const MAX_BODY = 16 * 1024;
|
|
1688
|
+
const chunks = [];
|
|
1689
|
+
let total = 0;
|
|
1690
|
+
let aborted = false;
|
|
1691
|
+
req.on("data", (chunk) => {
|
|
1692
|
+
if (aborted) return;
|
|
1693
|
+
total += chunk.length;
|
|
1694
|
+
if (total > MAX_BODY) {
|
|
1695
|
+
aborted = true;
|
|
1696
|
+
res.writeHead(413, CORS_HEADERS);
|
|
1697
|
+
res.end();
|
|
1698
|
+
return;
|
|
1699
|
+
}
|
|
1700
|
+
chunks.push(chunk);
|
|
1701
|
+
});
|
|
1702
|
+
req.on("end", () => {
|
|
1703
|
+
if (aborted) return;
|
|
1704
|
+
let parsed;
|
|
1705
|
+
try {
|
|
1706
|
+
parsed = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
1707
|
+
} catch {
|
|
1708
|
+
res.writeHead(400, { ...CORS_HEADERS, "Content-Type": "application/json" });
|
|
1709
|
+
res.end(JSON.stringify({ error: "invalid_json" }));
|
|
1710
|
+
setTimeout(() => {
|
|
1711
|
+
server.close();
|
|
1712
|
+
reject(new Error("Authentication failed: invalid JSON body"));
|
|
1713
|
+
}, 200);
|
|
1714
|
+
return;
|
|
1715
|
+
}
|
|
1716
|
+
const token = parsed?.token;
|
|
1717
|
+
if (!token || typeof token !== "string") {
|
|
1718
|
+
res.writeHead(400, { ...CORS_HEADERS, "Content-Type": "application/json" });
|
|
1719
|
+
res.end(JSON.stringify({ error: "missing_token" }));
|
|
1720
|
+
setTimeout(() => {
|
|
1721
|
+
server.close();
|
|
1722
|
+
reject(new Error("Authentication failed: missing token"));
|
|
1723
|
+
}, 200);
|
|
1724
|
+
return;
|
|
1725
|
+
}
|
|
1726
|
+
const authData = {
|
|
1727
|
+
access_token: token,
|
|
1728
|
+
refresh_token: typeof parsed.refresh_token === "string" ? parsed.refresh_token : "",
|
|
1729
|
+
user_id: typeof parsed.user_id === "string" ? parsed.user_id : void 0,
|
|
1730
|
+
email: typeof parsed.email === "string" ? parsed.email : void 0,
|
|
1731
|
+
org_id: typeof parsed.org_id === "string" ? parsed.org_id : void 0,
|
|
1732
|
+
state: typeof parsed.state === "string" ? parsed.state : void 0
|
|
1733
|
+
};
|
|
1734
|
+
res.writeHead(200, { ...CORS_HEADERS, "Content-Type": "application/json" });
|
|
1735
|
+
res.end(JSON.stringify({ ok: true }));
|
|
1736
|
+
setTimeout(() => {
|
|
1737
|
+
server.close();
|
|
1738
|
+
resolve2(authData);
|
|
1739
|
+
}, 200);
|
|
1740
|
+
});
|
|
1741
|
+
req.on("error", (e) => {
|
|
1742
|
+
if (aborted) return;
|
|
1743
|
+
aborted = true;
|
|
1744
|
+
try {
|
|
1745
|
+
res.writeHead(500, CORS_HEADERS);
|
|
1746
|
+
res.end();
|
|
1747
|
+
} catch {
|
|
1748
|
+
}
|
|
1749
|
+
setTimeout(() => {
|
|
1750
|
+
server.close();
|
|
1751
|
+
reject(e);
|
|
1752
|
+
}, 200);
|
|
1753
|
+
});
|
|
1639
1754
|
});
|
|
1640
1755
|
server.listen(PORT);
|
|
1641
1756
|
server.on("error", (error) => {
|
|
@@ -1713,80 +1828,13 @@ function clearCredentials() {
|
|
|
1713
1828
|
unlinkSync2(AUTH_FILE);
|
|
1714
1829
|
}
|
|
1715
1830
|
}
|
|
1716
|
-
var PORT, SYNKRO_WEB_AUTH_URL, AUTH_FILE,
|
|
1831
|
+
var PORT, SYNKRO_WEB_AUTH_URL, AUTH_FILE, ERROR_HTML;
|
|
1717
1832
|
var init_stub = __esm({
|
|
1718
1833
|
"cli/auth/stub.ts"() {
|
|
1719
1834
|
"use strict";
|
|
1720
1835
|
PORT = 8100;
|
|
1721
|
-
SYNKRO_WEB_AUTH_URL = process.env.SYNKRO_WEB_AUTH_URL || "
|
|
1836
|
+
SYNKRO_WEB_AUTH_URL = process.env.SYNKRO_WEB_AUTH_URL || "https://app.synkro.sh";
|
|
1722
1837
|
AUTH_FILE = process.env.SYNKRO_AUTH_FILE || join3(homedir3(), ".synkro", "credentials.json");
|
|
1723
|
-
SUCCESS_HTML = `
|
|
1724
|
-
<!DOCTYPE html>
|
|
1725
|
-
<html>
|
|
1726
|
-
<head>
|
|
1727
|
-
<title>Authentication Successful - Synkro CLI</title>
|
|
1728
|
-
<style>
|
|
1729
|
-
body {
|
|
1730
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
1731
|
-
display: flex;
|
|
1732
|
-
justify-content: center;
|
|
1733
|
-
align-items: center;
|
|
1734
|
-
height: 100vh;
|
|
1735
|
-
margin: 0;
|
|
1736
|
-
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
1737
|
-
}
|
|
1738
|
-
.container {
|
|
1739
|
-
background: white;
|
|
1740
|
-
padding: 3rem;
|
|
1741
|
-
border-radius: 1rem;
|
|
1742
|
-
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
|
|
1743
|
-
text-align: center;
|
|
1744
|
-
max-width: 400px;
|
|
1745
|
-
}
|
|
1746
|
-
.checkmark {
|
|
1747
|
-
width: 80px;
|
|
1748
|
-
height: 80px;
|
|
1749
|
-
border-radius: 50%;
|
|
1750
|
-
background: #10b981;
|
|
1751
|
-
margin: 0 auto 1.5rem;
|
|
1752
|
-
display: flex;
|
|
1753
|
-
align-items: center;
|
|
1754
|
-
justify-content: center;
|
|
1755
|
-
}
|
|
1756
|
-
.checkmark svg {
|
|
1757
|
-
width: 50px;
|
|
1758
|
-
height: 50px;
|
|
1759
|
-
stroke: white;
|
|
1760
|
-
}
|
|
1761
|
-
h1 {
|
|
1762
|
-
color: #1f2937;
|
|
1763
|
-
margin: 0 0 0.5rem;
|
|
1764
|
-
}
|
|
1765
|
-
p {
|
|
1766
|
-
color: #6b7280;
|
|
1767
|
-
margin: 0;
|
|
1768
|
-
}
|
|
1769
|
-
.close-note {
|
|
1770
|
-
margin-top: 1.5rem;
|
|
1771
|
-
font-size: 0.875rem;
|
|
1772
|
-
color: #9ca3af;
|
|
1773
|
-
}
|
|
1774
|
-
</style>
|
|
1775
|
-
</head>
|
|
1776
|
-
<body>
|
|
1777
|
-
<div class="container">
|
|
1778
|
-
<div class="checkmark">
|
|
1779
|
-
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
1780
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"></path>
|
|
1781
|
-
</svg>
|
|
1782
|
-
</div>
|
|
1783
|
-
<h1>Authentication Successful!</h1>
|
|
1784
|
-
<p>Your Synkro CLI has been authenticated.</p>
|
|
1785
|
-
<p class="close-note">You can close this window and return to your terminal.</p>
|
|
1786
|
-
</div>
|
|
1787
|
-
</body>
|
|
1788
|
-
</html>
|
|
1789
|
-
`;
|
|
1790
1838
|
ERROR_HTML = `
|
|
1791
1839
|
<!DOCTYPE html>
|
|
1792
1840
|
<html>
|
|
@@ -1865,22 +1913,26 @@ function writeGraderDaemon() {
|
|
|
1865
1913
|
}
|
|
1866
1914
|
function writeHookScripts() {
|
|
1867
1915
|
const bashScriptPath = join4(HOOKS_DIR, "cc-bash-judge.sh");
|
|
1916
|
+
const bashFollowupScriptPath = join4(HOOKS_DIR, "cc-bash-followup.sh");
|
|
1868
1917
|
const editCaptureScriptPath = join4(HOOKS_DIR, "cc-edit-capture.sh");
|
|
1869
1918
|
const editPrecheckScriptPath = join4(HOOKS_DIR, "cc-edit-precheck.sh");
|
|
1870
1919
|
const stopSummaryScriptPath = join4(HOOKS_DIR, "cc-stop-summary.sh");
|
|
1871
1920
|
const sessionStartScriptPath = join4(HOOKS_DIR, "cc-session-start.sh");
|
|
1872
1921
|
writeFileSync4(bashScriptPath, CC_BASH_JUDGE_SCRIPT, "utf-8");
|
|
1922
|
+
writeFileSync4(bashFollowupScriptPath, CC_BASH_FOLLOWUP_SCRIPT, "utf-8");
|
|
1873
1923
|
writeFileSync4(editCaptureScriptPath, CC_EDIT_CAPTURE_SCRIPT, "utf-8");
|
|
1874
1924
|
writeFileSync4(editPrecheckScriptPath, CC_EDIT_PRECHECK_SCRIPT, "utf-8");
|
|
1875
1925
|
writeFileSync4(stopSummaryScriptPath, CC_STOP_SUMMARY_SCRIPT, "utf-8");
|
|
1876
1926
|
writeFileSync4(sessionStartScriptPath, CC_SESSION_START_SCRIPT, "utf-8");
|
|
1877
1927
|
chmodSync(bashScriptPath, 493);
|
|
1928
|
+
chmodSync(bashFollowupScriptPath, 493);
|
|
1878
1929
|
chmodSync(editCaptureScriptPath, 493);
|
|
1879
1930
|
chmodSync(editPrecheckScriptPath, 493);
|
|
1880
1931
|
chmodSync(stopSummaryScriptPath, 493);
|
|
1881
1932
|
chmodSync(sessionStartScriptPath, 493);
|
|
1882
1933
|
return {
|
|
1883
1934
|
bashScript: bashScriptPath,
|
|
1935
|
+
bashFollowupScript: bashFollowupScriptPath,
|
|
1884
1936
|
editCaptureScript: editCaptureScriptPath,
|
|
1885
1937
|
editPrecheckScript: editPrecheckScriptPath,
|
|
1886
1938
|
stopSummaryScript: stopSummaryScriptPath,
|
|
@@ -1910,7 +1962,7 @@ function writeConfigEnv(opts) {
|
|
|
1910
1962
|
`SYNKRO_GATEWAY_URL=${shellQuoteSingle(safeGateway)}`,
|
|
1911
1963
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
1912
1964
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
1913
|
-
`SYNKRO_VERSION
|
|
1965
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.0.4")}`
|
|
1914
1966
|
];
|
|
1915
1967
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
1916
1968
|
if (safeOrgId) lines.push(`SYNKRO_ORG_ID=${shellQuoteSingle(safeOrgId)}`);
|
|
@@ -1942,7 +1994,7 @@ function assertGatewayAllowed(gatewayUrl) {
|
|
|
1942
1994
|
}
|
|
1943
1995
|
}
|
|
1944
1996
|
async function installCommand(opts = {}) {
|
|
1945
|
-
const gatewayUrl = opts.gatewayUrl || process.env.SYNKRO_GATEWAY_URL || "
|
|
1997
|
+
const gatewayUrl = opts.gatewayUrl || process.env.SYNKRO_GATEWAY_URL || "https://api.synkro.sh";
|
|
1946
1998
|
try {
|
|
1947
1999
|
assertGatewayAllowed(gatewayUrl);
|
|
1948
2000
|
} catch (err) {
|
|
@@ -1972,7 +2024,7 @@ async function installCommand(opts = {}) {
|
|
|
1972
2024
|
}
|
|
1973
2025
|
});
|
|
1974
2026
|
if (!result) {
|
|
1975
|
-
console.error("Authentication failed.
|
|
2027
|
+
console.error("Authentication failed. If you are running a self-hosted dashboard, set SYNKRO_WEB_AUTH_URL to its origin.");
|
|
1976
2028
|
process.exit(1);
|
|
1977
2029
|
}
|
|
1978
2030
|
}
|
|
@@ -1995,6 +2047,7 @@ async function installCommand(opts = {}) {
|
|
|
1995
2047
|
const scripts = writeHookScripts();
|
|
1996
2048
|
console.log("Wrote hook scripts:");
|
|
1997
2049
|
console.log(` ${scripts.bashScript}`);
|
|
2050
|
+
console.log(` ${scripts.bashFollowupScript}`);
|
|
1998
2051
|
console.log(` ${scripts.editCaptureScript}`);
|
|
1999
2052
|
console.log(` ${scripts.editPrecheckScript}`);
|
|
2000
2053
|
console.log(` ${scripts.stopSummaryScript}`);
|
|
@@ -2012,6 +2065,7 @@ async function installCommand(opts = {}) {
|
|
|
2012
2065
|
hasClaudeCode = true;
|
|
2013
2066
|
installCCHooks(agent.settingsPath, {
|
|
2014
2067
|
bashJudgeScriptPath: scripts.bashScript,
|
|
2068
|
+
bashFollowupScriptPath: scripts.bashFollowupScript,
|
|
2015
2069
|
editCaptureScriptPath: scripts.editCaptureScript,
|
|
2016
2070
|
editPrecheckScriptPath: scripts.editPrecheckScript,
|
|
2017
2071
|
stopSummaryScriptPath: scripts.stopSummaryScript,
|
|
@@ -2233,11 +2287,15 @@ function statusCommand() {
|
|
|
2233
2287
|
}
|
|
2234
2288
|
console.log();
|
|
2235
2289
|
const bashScript = join5(SYNKRO_DIR2, "hooks", "cc-bash-judge.sh");
|
|
2290
|
+
const bashFollowupScript = join5(SYNKRO_DIR2, "hooks", "cc-bash-followup.sh");
|
|
2291
|
+
const editPrecheckScript = join5(SYNKRO_DIR2, "hooks", "cc-edit-precheck.sh");
|
|
2236
2292
|
const editCaptureScript = join5(SYNKRO_DIR2, "hooks", "cc-edit-capture.sh");
|
|
2237
2293
|
const stopSummaryScript = join5(SYNKRO_DIR2, "hooks", "cc-stop-summary.sh");
|
|
2238
2294
|
const sessionStartScript = join5(SYNKRO_DIR2, "hooks", "cc-session-start.sh");
|
|
2239
2295
|
console.log("Hook scripts:");
|
|
2240
2296
|
console.log(` ${existsSync6(bashScript) ? "\u2713" : "\u2717"} ${bashScript}`);
|
|
2297
|
+
console.log(` ${existsSync6(bashFollowupScript) ? "\u2713" : "\u2717"} ${bashFollowupScript}`);
|
|
2298
|
+
console.log(` ${existsSync6(editPrecheckScript) ? "\u2713" : "\u2717"} ${editPrecheckScript}`);
|
|
2241
2299
|
console.log(` ${existsSync6(editCaptureScript) ? "\u2713" : "\u2717"} ${editCaptureScript}`);
|
|
2242
2300
|
console.log(` ${existsSync6(stopSummaryScript) ? "\u2713" : "\u2717"} ${stopSummaryScript}`);
|
|
2243
2301
|
console.log(` ${existsSync6(sessionStartScript) ? "\u2713" : "\u2717"} ${sessionStartScript}`);
|