pushary 1.8.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/CHANGELOG.md +1943 -0
- package/LICENSE +21 -0
- package/README.md +330 -0
- package/data/SKILL.md +591 -0
- package/data/cowork/SKILL.md +77 -0
- package/data/cursor-plugin/.cursor-plugin/plugin.json +25 -0
- package/data/cursor-plugin/CHANGELOG.md +70 -0
- package/data/cursor-plugin/CONTRIBUTING.md +40 -0
- package/data/cursor-plugin/LICENSE +21 -0
- package/data/cursor-plugin/README.md +113 -0
- package/data/cursor-plugin/SECURITY.md +33 -0
- package/data/cursor-plugin/assets/logo.png +0 -0
- package/data/cursor-plugin/commands/notify-when-done.md +14 -0
- package/data/cursor-plugin/commands/pushary-test.md +13 -0
- package/data/cursor-plugin/hooks/hooks.json +75 -0
- package/data/cursor-plugin/mcp.json +11 -0
- package/data/cursor-plugin/rules/pushary.mdc +40 -0
- package/data/cursor-plugin/scripts/pushary-gate.mjs +724 -0
- package/data/cursor-plugin/scripts/pushary-gate.test.mjs +137 -0
- package/data/cursor-plugin/scripts/redaction.mjs +51 -0
- package/data/cursor-plugin/skills/pushary/SKILL.md +584 -0
- package/data/vscode-plugin/.claude-plugin/plugin.json +28 -0
- package/data/vscode-plugin/.mcp.json +11 -0
- package/data/vscode-plugin/CHANGELOG.md +49 -0
- package/data/vscode-plugin/CONTRIBUTING.md +40 -0
- package/data/vscode-plugin/LICENSE +21 -0
- package/data/vscode-plugin/README.md +128 -0
- package/data/vscode-plugin/SECURITY.md +56 -0
- package/data/vscode-plugin/assets/logo.png +0 -0
- package/data/vscode-plugin/commands/notify-when-done.md +14 -0
- package/data/vscode-plugin/commands/pushary-test.md +13 -0
- package/data/vscode-plugin/hooks/hooks.json +60 -0
- package/data/vscode-plugin/scripts/pushary-gate.mjs +762 -0
- package/data/vscode-plugin/scripts/redaction.mjs +51 -0
- package/data/vscode-plugin/skills/pushary/SKILL.md +584 -0
- package/dist/bin/pushary-bell-hook.d.ts +1 -0
- package/dist/bin/pushary-bell-hook.js +46 -0
- package/dist/bin/pushary-bell.d.ts +1 -0
- package/dist/bin/pushary-bell.js +146 -0
- package/dist/bin/pushary-claude.d.ts +1 -0
- package/dist/bin/pushary-claude.js +1916 -0
- package/dist/bin/pushary-clean.d.ts +1 -0
- package/dist/bin/pushary-clean.js +1300 -0
- package/dist/bin/pushary-codex-bridge.d.ts +1 -0
- package/dist/bin/pushary-codex-bridge.js +599 -0
- package/dist/bin/pushary-codex-hook.d.ts +1 -0
- package/dist/bin/pushary-codex-hook.js +886 -0
- package/dist/bin/pushary-codex.d.ts +1 -0
- package/dist/bin/pushary-codex.js +125 -0
- package/dist/bin/pushary-connect.d.ts +1 -0
- package/dist/bin/pushary-connect.js +100 -0
- package/dist/bin/pushary-cowork.d.ts +1 -0
- package/dist/bin/pushary-cowork.js +36 -0
- package/dist/bin/pushary-daemon-supervisor.d.ts +1 -0
- package/dist/bin/pushary-daemon-supervisor.js +27 -0
- package/dist/bin/pushary-daemon.d.ts +1 -0
- package/dist/bin/pushary-daemon.js +878 -0
- package/dist/bin/pushary-disconnect.d.ts +1 -0
- package/dist/bin/pushary-disconnect.js +264 -0
- package/dist/bin/pushary-doctor.d.ts +1 -0
- package/dist/bin/pushary-doctor.js +1433 -0
- package/dist/bin/pushary-elicitation-hook.d.ts +1 -0
- package/dist/bin/pushary-elicitation-hook.js +149 -0
- package/dist/bin/pushary-gemini-bridge.d.ts +1 -0
- package/dist/bin/pushary-gemini-bridge.js +339 -0
- package/dist/bin/pushary-gemini-hook.d.ts +1 -0
- package/dist/bin/pushary-gemini-hook.js +381 -0
- package/dist/bin/pushary-hook.d.ts +1 -0
- package/dist/bin/pushary-hook.js +95 -0
- package/dist/bin/pushary-login.d.ts +1 -0
- package/dist/bin/pushary-login.js +198 -0
- package/dist/bin/pushary-logout.d.ts +1 -0
- package/dist/bin/pushary-logout.js +147 -0
- package/dist/bin/pushary-mcp.d.ts +1 -0
- package/dist/bin/pushary-mcp.js +114 -0
- package/dist/bin/pushary-mode.d.ts +1 -0
- package/dist/bin/pushary-mode.js +130 -0
- package/dist/bin/pushary-notification-hook.d.ts +1 -0
- package/dist/bin/pushary-notification-hook.js +56 -0
- package/dist/bin/pushary-opencode-hook.d.ts +1 -0
- package/dist/bin/pushary-opencode-hook.js +338 -0
- package/dist/bin/pushary-permission-denied-hook.d.ts +1 -0
- package/dist/bin/pushary-permission-denied-hook.js +60 -0
- package/dist/bin/pushary-permission-hook.d.ts +1 -0
- package/dist/bin/pushary-permission-hook.js +65 -0
- package/dist/bin/pushary-post-hook.d.ts +1 -0
- package/dist/bin/pushary-post-hook.js +70 -0
- package/dist/bin/pushary-prompt-hook.d.ts +1 -0
- package/dist/bin/pushary-prompt-hook.js +61 -0
- package/dist/bin/pushary-session-end-hook.d.ts +1 -0
- package/dist/bin/pushary-session-end-hook.js +59 -0
- package/dist/bin/pushary-session-start-hook.d.ts +1 -0
- package/dist/bin/pushary-session-start-hook.js +72 -0
- package/dist/bin/pushary-setup.d.ts +1 -0
- package/dist/bin/pushary-setup.js +2660 -0
- package/dist/bin/pushary-stats.d.ts +1 -0
- package/dist/bin/pushary-stats.js +44 -0
- package/dist/bin/pushary-status.d.ts +1 -0
- package/dist/bin/pushary-status.js +262 -0
- package/dist/bin/pushary-stop-hook.d.ts +1 -0
- package/dist/bin/pushary-stop-hook.js +63 -0
- package/dist/bin/pushary-stopfailure-hook.d.ts +1 -0
- package/dist/bin/pushary-stopfailure-hook.js +56 -0
- package/dist/bin/pushary-suggestions.d.ts +1 -0
- package/dist/bin/pushary-suggestions.js +100 -0
- package/dist/bin/pushary-transcript-register.d.ts +1 -0
- package/dist/bin/pushary-transcript-register.js +40 -0
- package/dist/bin/pushary-transcripts.d.ts +1 -0
- package/dist/bin/pushary-transcripts.js +77 -0
- package/dist/bin/pushary-upgrade.d.ts +1 -0
- package/dist/bin/pushary-upgrade.js +599 -0
- package/dist/bin/pushary-wait.d.ts +1 -0
- package/dist/bin/pushary-wait.js +122 -0
- package/dist/bin/pushary.d.ts +1 -0
- package/dist/bin/pushary.js +74 -0
- package/dist/chunk-2ABTSGFT.js +173 -0
- package/dist/chunk-2OY3ZZ5N.js +124 -0
- package/dist/chunk-3EGEA4KH.js +44 -0
- package/dist/chunk-3EVPNIBE.js +185 -0
- package/dist/chunk-5OP5MQI7.js +45 -0
- package/dist/chunk-6J2JC2RT.js +149 -0
- package/dist/chunk-7QLSKOSU.js +19 -0
- package/dist/chunk-7Z7Q4GGS.js +88 -0
- package/dist/chunk-A2A2YTMG.js +835 -0
- package/dist/chunk-AHV4LNB5.js +377 -0
- package/dist/chunk-AXPCESYO.js +197 -0
- package/dist/chunk-C2WCPBF7.js +86 -0
- package/dist/chunk-CJVVKOSR.js +73 -0
- package/dist/chunk-CULUZTWQ.js +2117 -0
- package/dist/chunk-CVQYGMSR.js +142 -0
- package/dist/chunk-CVWG2N3Y.js +16 -0
- package/dist/chunk-D2FX3EPW.js +15 -0
- package/dist/chunk-DB3ONZB4.js +44 -0
- package/dist/chunk-DE4Y6TCC.js +160 -0
- package/dist/chunk-E4FJTUH4.js +249 -0
- package/dist/chunk-EPCXUP3P.js +41 -0
- package/dist/chunk-EX3GAPA4.js +44 -0
- package/dist/chunk-EYK3GSRH.js +143 -0
- package/dist/chunk-GMXKITVA.js +70 -0
- package/dist/chunk-GPEGOGRJ.js +49 -0
- package/dist/chunk-GU3EJCVV.js +43 -0
- package/dist/chunk-HQ6G3B5R.js +59 -0
- package/dist/chunk-HZVVNGEW.js +22 -0
- package/dist/chunk-IPVKH2ST.js +231 -0
- package/dist/chunk-J5TIV3J6.js +238 -0
- package/dist/chunk-JU6W3XAU.js +64 -0
- package/dist/chunk-JYG4B33G.js +227 -0
- package/dist/chunk-JZTHGAPA.js +503 -0
- package/dist/chunk-KGDWDSNL.js +102 -0
- package/dist/chunk-KVQBWI5T.js +99 -0
- package/dist/chunk-KZERVKTD.js +16 -0
- package/dist/chunk-LXQ5FBBD.js +47 -0
- package/dist/chunk-M5ICYGHT.js +138 -0
- package/dist/chunk-M5JDZ45W.js +943 -0
- package/dist/chunk-MDEPU45E.js +1226 -0
- package/dist/chunk-MPWXGONV.js +157 -0
- package/dist/chunk-N6IOSZOE.js +185 -0
- package/dist/chunk-NGDD6TXY.js +192 -0
- package/dist/chunk-NQTHFF4W.js +2830 -0
- package/dist/chunk-OKXS7WDZ.js +68 -0
- package/dist/chunk-OLQRRFBX.js +21 -0
- package/dist/chunk-P7WQEVWA.js +307 -0
- package/dist/chunk-POFBE6ZY.js +12 -0
- package/dist/chunk-PQ4K74WL.js +30 -0
- package/dist/chunk-PUZZELE6.js +37 -0
- package/dist/chunk-Q7E4I6UA.js +767 -0
- package/dist/chunk-QCGNGEGE.js +15 -0
- package/dist/chunk-R7437YI3.js +151 -0
- package/dist/chunk-RHR6NARM.js +305 -0
- package/dist/chunk-SAXBC4AZ.js +60 -0
- package/dist/chunk-SGZJ5LYH.js +76 -0
- package/dist/chunk-SIFVFP6T.js +70 -0
- package/dist/chunk-SLFABHW3.js +150 -0
- package/dist/chunk-T7E75EKA.js +67 -0
- package/dist/chunk-TY4JT7W3.js +38 -0
- package/dist/chunk-U4TMAANR.js +111 -0
- package/dist/chunk-UI36QSBI.js +177 -0
- package/dist/chunk-VQKRG3AC.js +339 -0
- package/dist/chunk-WE2J62NC.js +1131 -0
- package/dist/chunk-XHKBHWLX.js +14 -0
- package/dist/chunk-ZSZSSJCV.js +275 -0
- package/dist/chunk-ZVSKMPBZ.js +135 -0
- package/dist/reapply-CW3MA66V.js +34 -0
- package/dist/src/index.d.ts +204 -0
- package/dist/src/index.js +64 -0
- package/package.json +108 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
readLedgerSummary
|
|
4
|
+
} from "../chunk-JU6W3XAU.js";
|
|
5
|
+
import {
|
|
6
|
+
exitOnHelpFlag
|
|
7
|
+
} from "../chunk-HZVVNGEW.js";
|
|
8
|
+
import "../chunk-KZERVKTD.js";
|
|
9
|
+
import {
|
|
10
|
+
getApiKey
|
|
11
|
+
} from "../chunk-GPEGOGRJ.js";
|
|
12
|
+
import "../chunk-E4FJTUH4.js";
|
|
13
|
+
import "../chunk-NQTHFF4W.js";
|
|
14
|
+
|
|
15
|
+
// bin/pushary-stats.ts
|
|
16
|
+
exitOnHelpFlag("stats");
|
|
17
|
+
var DAYS = 7;
|
|
18
|
+
var summary = readLedgerSummary(DAYS);
|
|
19
|
+
var connected = true;
|
|
20
|
+
try {
|
|
21
|
+
getApiKey();
|
|
22
|
+
} catch {
|
|
23
|
+
connected = false;
|
|
24
|
+
}
|
|
25
|
+
var plural = (count, word) => count === 1 ? word : `${word}s`;
|
|
26
|
+
if (summary.count === 0) {
|
|
27
|
+
if (connected) {
|
|
28
|
+
console.log("No locally counted approval moments in the last 7 days. Connected sessions land in your dashboard: https://pushary.com/dashboard/agent/activity");
|
|
29
|
+
} else {
|
|
30
|
+
console.log("No approval moments counted yet. Run your agent with the Pushary hooks installed and check back after a session or two.");
|
|
31
|
+
}
|
|
32
|
+
process.exit(0);
|
|
33
|
+
}
|
|
34
|
+
var toolLines = Object.entries(summary.byTool).sort((a, b) => b[1] - a[1]).map(([tool, count]) => ` ${tool}: ${count}`).join("\n");
|
|
35
|
+
console.log(`In the last ${DAYS} days, your agents hit ${summary.count} approval ${plural(summary.count, "moment")} across ${summary.sessions} ${plural(summary.sessions, "session")} while Pushary was not connected:
|
|
36
|
+
`);
|
|
37
|
+
console.log(toolLines);
|
|
38
|
+
console.log();
|
|
39
|
+
if (connected) {
|
|
40
|
+
console.log("A key is configured now, so new moments reach your phone instead of waiting in the terminal.");
|
|
41
|
+
} else {
|
|
42
|
+
console.log("Each of those sat in the terminal until you noticed. With Pushary they land on your lock screen as a yes or no.");
|
|
43
|
+
console.log("3-day trial: https://pushary.com/sign-up?utm_source=cli&utm_medium=stats");
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
describeLastSeen,
|
|
4
|
+
listMachines
|
|
5
|
+
} from "../chunk-DE4Y6TCC.js";
|
|
6
|
+
import "../chunk-HQ6G3B5R.js";
|
|
7
|
+
import "../chunk-WE2J62NC.js";
|
|
8
|
+
import "../chunk-XHKBHWLX.js";
|
|
9
|
+
import {
|
|
10
|
+
describeReach,
|
|
11
|
+
fetchChannels,
|
|
12
|
+
reachVerdict
|
|
13
|
+
} from "../chunk-M5JDZ45W.js";
|
|
14
|
+
import "../chunk-3EGEA4KH.js";
|
|
15
|
+
import "../chunk-QCGNGEGE.js";
|
|
16
|
+
import {
|
|
17
|
+
createIo
|
|
18
|
+
} from "../chunk-U4TMAANR.js";
|
|
19
|
+
import {
|
|
20
|
+
exitOnHelpFlag
|
|
21
|
+
} from "../chunk-HZVVNGEW.js";
|
|
22
|
+
import {
|
|
23
|
+
rejectUnknownFlags
|
|
24
|
+
} from "../chunk-GMXKITVA.js";
|
|
25
|
+
import {
|
|
26
|
+
readKeySource
|
|
27
|
+
} from "../chunk-P7WQEVWA.js";
|
|
28
|
+
import "../chunk-M5ICYGHT.js";
|
|
29
|
+
import {
|
|
30
|
+
checkApiKey,
|
|
31
|
+
describeKeyCheck
|
|
32
|
+
} from "../chunk-2ABTSGFT.js";
|
|
33
|
+
import "../chunk-2OY3ZZ5N.js";
|
|
34
|
+
import "../chunk-LXQ5FBBD.js";
|
|
35
|
+
import {
|
|
36
|
+
UsageError
|
|
37
|
+
} from "../chunk-7QLSKOSU.js";
|
|
38
|
+
import {
|
|
39
|
+
EXIT
|
|
40
|
+
} from "../chunk-KZERVKTD.js";
|
|
41
|
+
import "../chunk-DB3ONZB4.js";
|
|
42
|
+
import "../chunk-A2A2YTMG.js";
|
|
43
|
+
import "../chunk-T7E75EKA.js";
|
|
44
|
+
import "../chunk-GPEGOGRJ.js";
|
|
45
|
+
import "../chunk-E4FJTUH4.js";
|
|
46
|
+
import "../chunk-NQTHFF4W.js";
|
|
47
|
+
|
|
48
|
+
// src/status.ts
|
|
49
|
+
var keySourceLine = (source) => {
|
|
50
|
+
if (source.kind === "none") {
|
|
51
|
+
return { label: "Key", value: "none found", ok: false };
|
|
52
|
+
}
|
|
53
|
+
const prefix = source.key ? source.key.split(".")[0] : "unknown";
|
|
54
|
+
const where = source.kind === "env" ? "$PUSHARY_API_KEY" : source.origin ?? "config file";
|
|
55
|
+
return { label: "Key", value: `${prefix} from ${where}`, ok: true };
|
|
56
|
+
};
|
|
57
|
+
var reachLine = (channels) => {
|
|
58
|
+
const verdict = reachVerdict(channels);
|
|
59
|
+
const line = describeReach(channels);
|
|
60
|
+
if (verdict.kind === "nobody") return { label: "Reachable", value: line, ok: false };
|
|
61
|
+
if (verdict.kind === "yours") {
|
|
62
|
+
const inPocket = (channels.yours?.phoneReachable ?? channels.phoneReachable) || channels.webPhone > 0;
|
|
63
|
+
return { label: "Reachable", value: line, ok: inPocket };
|
|
64
|
+
}
|
|
65
|
+
return { label: "Reachable", value: line, ok: false };
|
|
66
|
+
};
|
|
67
|
+
var siteLine = (channels) => {
|
|
68
|
+
const site = channels.site;
|
|
69
|
+
if (site === null || site.otherMembers === 0) return null;
|
|
70
|
+
const devices2 = site.appDevices + site.webActive;
|
|
71
|
+
return {
|
|
72
|
+
label: "Team",
|
|
73
|
+
value: `${devices2} device${devices2 === 1 ? "" : "s"} across ${site.otherMembers + 1} members`,
|
|
74
|
+
ok: null
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
var buildStatusReport = (facts) => {
|
|
78
|
+
const lines = [keySourceLine(facts.source)];
|
|
79
|
+
if (facts.source.drift) {
|
|
80
|
+
lines.push({
|
|
81
|
+
label: "Key drift",
|
|
82
|
+
value: `$PUSHARY_API_KEY (${facts.source.drift.envPrefix}) differs from ${facts.source.drift.configPath} (${facts.source.drift.configPrefix}); the environment wins`,
|
|
83
|
+
ok: false
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
if (facts.source.kind === "none") {
|
|
87
|
+
return {
|
|
88
|
+
lines,
|
|
89
|
+
headline: "Not set up on this machine.",
|
|
90
|
+
next: ["Run `pushary setup` to connect an agent."],
|
|
91
|
+
exitCode: EXIT.NOT_CONFIGURED
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
const check = facts.keyCheck;
|
|
95
|
+
if (check && check.kind !== "ok") {
|
|
96
|
+
const report = describeKeyCheck(check);
|
|
97
|
+
lines.push({ label: "Server", value: report.message, ok: check.kind === "unreachable" ? null : false });
|
|
98
|
+
return { lines, headline: report.message, next: [...report.next], exitCode: report.exitCode };
|
|
99
|
+
}
|
|
100
|
+
if (check?.kind === "ok") {
|
|
101
|
+
const id = check.identity;
|
|
102
|
+
lines.push({ label: "Site", value: `${id.siteName || id.siteSlug} (${id.siteSlug})`, ok: true });
|
|
103
|
+
lines.push({
|
|
104
|
+
label: "Plan",
|
|
105
|
+
value: id.plan === id.surfacePlan ? `${id.plan} \xB7 ${id.subscriptionStatus}` : `${id.plan} (from ${id.surfacePlan}) \xB7 ${id.subscriptionStatus}`,
|
|
106
|
+
ok: true
|
|
107
|
+
});
|
|
108
|
+
if (id.workspaceMembers > 1) {
|
|
109
|
+
lines.push({
|
|
110
|
+
label: "Workspace",
|
|
111
|
+
value: `${id.workspaceMembers} members \u2014 some devices below may not be yours`,
|
|
112
|
+
ok: null
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const channels = facts.channels?.kind === "ok" ? facts.channels.status : null;
|
|
117
|
+
if (channels) {
|
|
118
|
+
lines.push(reachLine(channels));
|
|
119
|
+
const site = siteLine(channels);
|
|
120
|
+
if (site) lines.push(site);
|
|
121
|
+
} else if (facts.channels && facts.channels.kind === "unreachable") {
|
|
122
|
+
lines.push({ label: "Reachable", value: `could not check (${facts.channels.detail})`, ok: null });
|
|
123
|
+
}
|
|
124
|
+
if (facts.source.drift) {
|
|
125
|
+
return {
|
|
126
|
+
lines,
|
|
127
|
+
headline: "Working, but two different keys are configured.",
|
|
128
|
+
next: [
|
|
129
|
+
"The shell export wins over the config file, and it may be the older one.",
|
|
130
|
+
"Run `pushary setup` to line them up, or open a new terminal."
|
|
131
|
+
],
|
|
132
|
+
exitCode: EXIT.PROBLEMS_FOUND
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (facts.channels && facts.channels.kind === "unreachable") {
|
|
136
|
+
return {
|
|
137
|
+
lines,
|
|
138
|
+
headline: "Key is fine; could not read which devices are connected.",
|
|
139
|
+
next: ["Run `pushary status` again in a minute."],
|
|
140
|
+
exitCode: EXIT.UNREACHABLE
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
if (channels) {
|
|
144
|
+
const verdict = reachVerdict(channels);
|
|
145
|
+
if (verdict.kind !== "yours") {
|
|
146
|
+
return {
|
|
147
|
+
lines,
|
|
148
|
+
headline: verdict.kind === "nobody" ? "Configured, but no device can receive an approval." : verdict.kind === "others" ? "Configured, but the only devices here are your teammates'." : "Configured, and nothing proves an approval reaches you.",
|
|
149
|
+
next: verdict.kind === "nobody" ? ["Run `pushary connect` to add your phone, or install the Pushary app."] : ["Run `pushary connect` to add your own phone.", "Or `pushary doctor --roundtrip` to prove one of these is yours."],
|
|
150
|
+
exitCode: EXIT.NO_DEVICE
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
if (!(channels.yours?.phoneReachable ?? channels.phoneReachable) && channels.webPhone === 0) {
|
|
154
|
+
return {
|
|
155
|
+
lines,
|
|
156
|
+
headline: "Configured, but nothing in your pocket can receive an approval.",
|
|
157
|
+
next: ["Run `pushary connect` and connect your phone, or install the Pushary app."],
|
|
158
|
+
exitCode: EXIT.NO_DEVICE
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
lines,
|
|
164
|
+
headline: "Ready.",
|
|
165
|
+
next: [],
|
|
166
|
+
exitCode: EXIT.OK
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
var statusJson = (facts, report) => ({
|
|
170
|
+
ok: report.exitCode === EXIT.OK,
|
|
171
|
+
headline: report.headline,
|
|
172
|
+
exitCode: report.exitCode,
|
|
173
|
+
keySource: facts.source.kind,
|
|
174
|
+
keyOrigin: facts.source.origin,
|
|
175
|
+
keyPrefix: facts.source.key ? facts.source.key.split(".")[0] : null,
|
|
176
|
+
drift: facts.source.drift ? {
|
|
177
|
+
env: facts.source.drift.envPrefix,
|
|
178
|
+
config: facts.source.drift.configPrefix,
|
|
179
|
+
configPath: facts.source.drift.configPath
|
|
180
|
+
} : null,
|
|
181
|
+
keyCheck: facts.keyCheck?.kind ?? null,
|
|
182
|
+
identity: facts.keyCheck?.kind === "ok" ? facts.keyCheck.identity : null,
|
|
183
|
+
channels: facts.channels?.kind === "ok" ? facts.channels.status : null,
|
|
184
|
+
channelsProbe: facts.channels?.kind ?? null
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// bin/pushary-status.ts
|
|
188
|
+
exitOnHelpFlag("status");
|
|
189
|
+
var { bold, dim, green, red, yellow } = createIo();
|
|
190
|
+
var args = process.argv.slice(2);
|
|
191
|
+
try {
|
|
192
|
+
rejectUnknownFlags(args.filter((a) => a !== "status"), ["--json", "--devices"]);
|
|
193
|
+
} catch (err) {
|
|
194
|
+
process.stderr.write(` ! ${err instanceof Error ? err.message : String(err)}
|
|
195
|
+
`);
|
|
196
|
+
process.exit(EXIT.USAGE);
|
|
197
|
+
}
|
|
198
|
+
var json = args.includes("--json");
|
|
199
|
+
var devices = args.includes("--devices");
|
|
200
|
+
var main = async () => {
|
|
201
|
+
const source = readKeySource();
|
|
202
|
+
let keyCheck = null;
|
|
203
|
+
let channels = null;
|
|
204
|
+
if (source.key) {
|
|
205
|
+
keyCheck = await checkApiKey(source.key);
|
|
206
|
+
if (keyCheck.kind === "ok") channels = await fetchChannels(source.key);
|
|
207
|
+
}
|
|
208
|
+
const machines = devices && keyCheck?.kind === "ok" ? await listMachines(source.key) : null;
|
|
209
|
+
const facts = { source, keyCheck, channels };
|
|
210
|
+
const report = buildStatusReport(facts);
|
|
211
|
+
if (json) {
|
|
212
|
+
const payload = statusJson(facts, report);
|
|
213
|
+
if (machines) {
|
|
214
|
+
payload.machines = machines.kind === "ok" ? machines.machines : [];
|
|
215
|
+
if (machines.kind !== "ok") payload.machinesUnavailable = machines.kind;
|
|
216
|
+
}
|
|
217
|
+
process.stdout.write(`${JSON.stringify(payload, null, 2)}
|
|
218
|
+
`);
|
|
219
|
+
process.exit(report.exitCode);
|
|
220
|
+
}
|
|
221
|
+
const width = Math.max(...report.lines.map((line) => line.label.length)) + 2;
|
|
222
|
+
console.log();
|
|
223
|
+
console.log(` ${bold("Pushary")}`);
|
|
224
|
+
console.log();
|
|
225
|
+
for (const line of report.lines) {
|
|
226
|
+
const icon = line.ok === true ? green("\u2713") : line.ok === false ? red("\u2717") : dim("\xB7");
|
|
227
|
+
console.log(` ${icon} ${line.label.padEnd(width)}${line.value}`);
|
|
228
|
+
}
|
|
229
|
+
if (machines) {
|
|
230
|
+
console.log();
|
|
231
|
+
console.log(` ${bold("Machines")}`);
|
|
232
|
+
if (machines.kind === "unsupported") {
|
|
233
|
+
console.log(` ${dim("This server does not report machines yet.")}`);
|
|
234
|
+
} else if (machines.kind === "failed") {
|
|
235
|
+
console.log(` ${dim(`Could not read the machine list (${machines.detail}).`)}`);
|
|
236
|
+
} else if (machines.machines.length === 0) {
|
|
237
|
+
console.log(` ${dim("None registered. Run")} pushary daemon ${dim("to keep a machine reachable.")}`);
|
|
238
|
+
} else {
|
|
239
|
+
const hostWidth = Math.max(...machines.machines.map((m) => m.hostname.length)) + 2;
|
|
240
|
+
for (const machine of machines.machines) {
|
|
241
|
+
const mark = machine.online ? green("\u25CF") : dim("\u25CB");
|
|
242
|
+
console.log(
|
|
243
|
+
` ${mark} ${machine.hostname.padEnd(hostWidth)}${dim(`${machine.cliVersion} ${describeLastSeen(machine.lastSeenAt)}`)}`
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
console.log();
|
|
249
|
+
console.log(` ${report.exitCode === 0 ? green(bold(report.headline)) : yellow(bold(report.headline))}`);
|
|
250
|
+
for (const next of report.next) console.log(` ${dim(next)}`);
|
|
251
|
+
console.log();
|
|
252
|
+
process.exit(report.exitCode);
|
|
253
|
+
};
|
|
254
|
+
main().catch((err) => {
|
|
255
|
+
if (err instanceof UsageError) {
|
|
256
|
+
process.stderr.write(` ! ${err.message}
|
|
257
|
+
`);
|
|
258
|
+
process.exit(EXIT.USAGE);
|
|
259
|
+
}
|
|
260
|
+
console.error(` ${yellow("!")} status failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
261
|
+
process.exit(1);
|
|
262
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
activeHookSource,
|
|
4
|
+
activeIdentity
|
|
5
|
+
} from "../chunk-J5TIV3J6.js";
|
|
6
|
+
import "../chunk-AXPCESYO.js";
|
|
7
|
+
import {
|
|
8
|
+
readHookInput
|
|
9
|
+
} from "../chunk-KGDWDSNL.js";
|
|
10
|
+
import "../chunk-JZTHGAPA.js";
|
|
11
|
+
import "../chunk-SGZJ5LYH.js";
|
|
12
|
+
import "../chunk-EYK3GSRH.js";
|
|
13
|
+
import "../chunk-ZVSKMPBZ.js";
|
|
14
|
+
import "../chunk-C2WCPBF7.js";
|
|
15
|
+
import "../chunk-6J2JC2RT.js";
|
|
16
|
+
import "../chunk-WE2J62NC.js";
|
|
17
|
+
import "../chunk-3EVPNIBE.js";
|
|
18
|
+
import "../chunk-OKXS7WDZ.js";
|
|
19
|
+
import "../chunk-MPWXGONV.js";
|
|
20
|
+
import "../chunk-SAXBC4AZ.js";
|
|
21
|
+
import "../chunk-OLQRRFBX.js";
|
|
22
|
+
import "../chunk-XHKBHWLX.js";
|
|
23
|
+
import {
|
|
24
|
+
handleStop,
|
|
25
|
+
handleSubagentStop,
|
|
26
|
+
isSubagentStop
|
|
27
|
+
} from "../chunk-CULUZTWQ.js";
|
|
28
|
+
import "../chunk-N6IOSZOE.js";
|
|
29
|
+
import "../chunk-EPCXUP3P.js";
|
|
30
|
+
import "../chunk-NGDD6TXY.js";
|
|
31
|
+
import "../chunk-CVQYGMSR.js";
|
|
32
|
+
import "../chunk-POFBE6ZY.js";
|
|
33
|
+
import "../chunk-GMXKITVA.js";
|
|
34
|
+
import "../chunk-P7WQEVWA.js";
|
|
35
|
+
import "../chunk-M5ICYGHT.js";
|
|
36
|
+
import "../chunk-2ABTSGFT.js";
|
|
37
|
+
import "../chunk-2OY3ZZ5N.js";
|
|
38
|
+
import "../chunk-LXQ5FBBD.js";
|
|
39
|
+
import "../chunk-7QLSKOSU.js";
|
|
40
|
+
import "../chunk-KZERVKTD.js";
|
|
41
|
+
import "../chunk-DB3ONZB4.js";
|
|
42
|
+
import "../chunk-A2A2YTMG.js";
|
|
43
|
+
import "../chunk-T7E75EKA.js";
|
|
44
|
+
import "../chunk-GPEGOGRJ.js";
|
|
45
|
+
import "../chunk-E4FJTUH4.js";
|
|
46
|
+
import "../chunk-NQTHFF4W.js";
|
|
47
|
+
|
|
48
|
+
// bin/pushary-stop-hook.ts
|
|
49
|
+
var AGENT = activeIdentity(process.argv);
|
|
50
|
+
var main = async () => {
|
|
51
|
+
const input = await readHookInput(activeHookSource(process.argv), "Stop");
|
|
52
|
+
if (!input) return;
|
|
53
|
+
try {
|
|
54
|
+
if (isSubagentStop(input)) {
|
|
55
|
+
await handleSubagentStop(input, AGENT);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const output = await handleStop(input, AGENT);
|
|
59
|
+
if (output) process.stdout.write(JSON.stringify(output));
|
|
60
|
+
} catch {
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
main();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
activeHookSource,
|
|
4
|
+
activeIdentity
|
|
5
|
+
} from "../chunk-J5TIV3J6.js";
|
|
6
|
+
import "../chunk-AXPCESYO.js";
|
|
7
|
+
import {
|
|
8
|
+
readHookInput
|
|
9
|
+
} from "../chunk-KGDWDSNL.js";
|
|
10
|
+
import "../chunk-JZTHGAPA.js";
|
|
11
|
+
import "../chunk-SGZJ5LYH.js";
|
|
12
|
+
import "../chunk-EYK3GSRH.js";
|
|
13
|
+
import "../chunk-ZVSKMPBZ.js";
|
|
14
|
+
import "../chunk-C2WCPBF7.js";
|
|
15
|
+
import "../chunk-6J2JC2RT.js";
|
|
16
|
+
import "../chunk-WE2J62NC.js";
|
|
17
|
+
import "../chunk-3EVPNIBE.js";
|
|
18
|
+
import "../chunk-OKXS7WDZ.js";
|
|
19
|
+
import "../chunk-MPWXGONV.js";
|
|
20
|
+
import "../chunk-SAXBC4AZ.js";
|
|
21
|
+
import "../chunk-OLQRRFBX.js";
|
|
22
|
+
import "../chunk-XHKBHWLX.js";
|
|
23
|
+
import {
|
|
24
|
+
handleStopFailure
|
|
25
|
+
} from "../chunk-CULUZTWQ.js";
|
|
26
|
+
import "../chunk-N6IOSZOE.js";
|
|
27
|
+
import "../chunk-EPCXUP3P.js";
|
|
28
|
+
import "../chunk-NGDD6TXY.js";
|
|
29
|
+
import "../chunk-CVQYGMSR.js";
|
|
30
|
+
import "../chunk-POFBE6ZY.js";
|
|
31
|
+
import "../chunk-GMXKITVA.js";
|
|
32
|
+
import "../chunk-P7WQEVWA.js";
|
|
33
|
+
import "../chunk-M5ICYGHT.js";
|
|
34
|
+
import "../chunk-2ABTSGFT.js";
|
|
35
|
+
import "../chunk-2OY3ZZ5N.js";
|
|
36
|
+
import "../chunk-LXQ5FBBD.js";
|
|
37
|
+
import "../chunk-7QLSKOSU.js";
|
|
38
|
+
import "../chunk-KZERVKTD.js";
|
|
39
|
+
import "../chunk-DB3ONZB4.js";
|
|
40
|
+
import "../chunk-A2A2YTMG.js";
|
|
41
|
+
import "../chunk-T7E75EKA.js";
|
|
42
|
+
import "../chunk-GPEGOGRJ.js";
|
|
43
|
+
import "../chunk-E4FJTUH4.js";
|
|
44
|
+
import "../chunk-NQTHFF4W.js";
|
|
45
|
+
|
|
46
|
+
// bin/pushary-stopfailure-hook.ts
|
|
47
|
+
var AGENT = activeIdentity(process.argv);
|
|
48
|
+
var main = async () => {
|
|
49
|
+
const input = await readHookInput(activeHookSource(process.argv), "StopFailure");
|
|
50
|
+
if (!input) return;
|
|
51
|
+
try {
|
|
52
|
+
await handleStopFailure(input, AGENT);
|
|
53
|
+
} catch {
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
main();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
createIo
|
|
4
|
+
} from "../chunk-U4TMAANR.js";
|
|
5
|
+
import {
|
|
6
|
+
exitOnHelpFlag
|
|
7
|
+
} from "../chunk-HZVVNGEW.js";
|
|
8
|
+
import {
|
|
9
|
+
rejectUnknownFlags
|
|
10
|
+
} from "../chunk-GMXKITVA.js";
|
|
11
|
+
import {
|
|
12
|
+
UsageError
|
|
13
|
+
} from "../chunk-7QLSKOSU.js";
|
|
14
|
+
import {
|
|
15
|
+
EXIT
|
|
16
|
+
} from "../chunk-KZERVKTD.js";
|
|
17
|
+
import {
|
|
18
|
+
getApiKey,
|
|
19
|
+
getBaseUrl
|
|
20
|
+
} from "../chunk-GPEGOGRJ.js";
|
|
21
|
+
import "../chunk-E4FJTUH4.js";
|
|
22
|
+
import "../chunk-NQTHFF4W.js";
|
|
23
|
+
|
|
24
|
+
// bin/pushary-suggestions.ts
|
|
25
|
+
exitOnHelpFlag("suggestions");
|
|
26
|
+
var { dim, green, cyan, red } = createIo();
|
|
27
|
+
var errorMessage = async (res) => {
|
|
28
|
+
try {
|
|
29
|
+
const body = await res.json();
|
|
30
|
+
return body.error ?? `HTTP ${res.status}`;
|
|
31
|
+
} catch {
|
|
32
|
+
return `HTTP ${res.status}`;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
{
|
|
36
|
+
const raw = process.argv.slice(2);
|
|
37
|
+
const positional = raw[0] === "suggestions" ? raw.slice(1) : raw;
|
|
38
|
+
try {
|
|
39
|
+
rejectUnknownFlags(positional, []);
|
|
40
|
+
} catch (err) {
|
|
41
|
+
process.stderr.write(` ! ${err instanceof Error ? err.message : String(err)}
|
|
42
|
+
`);
|
|
43
|
+
process.exit(EXIT.USAGE);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
var main = async () => {
|
|
47
|
+
const apiKey = getApiKey();
|
|
48
|
+
const baseUrl = getBaseUrl();
|
|
49
|
+
const headers = { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" };
|
|
50
|
+
const rest = process.argv.slice(2);
|
|
51
|
+
const args = rest[0] === "suggestions" ? rest.slice(1) : rest;
|
|
52
|
+
const sub = args[0];
|
|
53
|
+
if (sub === "accept") {
|
|
54
|
+
const id = args[1];
|
|
55
|
+
if (!id) {
|
|
56
|
+
console.error("Usage: pushary suggestions accept <id>");
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
const res2 = await fetch(`${baseUrl}/api/mcp/suggestions`, {
|
|
60
|
+
method: "POST",
|
|
61
|
+
headers,
|
|
62
|
+
body: JSON.stringify({ id })
|
|
63
|
+
});
|
|
64
|
+
if (!res2.ok) {
|
|
65
|
+
console.error(` ${red("\u2717")} ${await errorMessage(res2)}`);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
console.log(` ${green("\u2713")} Accepted. The rule is live now; your agents will pick it up on their next check.`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const res = await fetch(`${baseUrl}/api/mcp/suggestions`, { headers });
|
|
72
|
+
if (!res.ok) {
|
|
73
|
+
console.error(` ${red("\u2717")} ${await errorMessage(res)}`);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
const { suggestions } = await res.json();
|
|
77
|
+
if (suggestions.length === 0) {
|
|
78
|
+
console.log(` ${dim("No pending suggestions. Keep approving; a rule is offered once a pattern is earned.")}`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
console.log(` ${suggestions.length} pending suggestion${suggestions.length === 1 ? "" : "s"}:
|
|
82
|
+
`);
|
|
83
|
+
for (const s of suggestions) {
|
|
84
|
+
const verb = s.kind === "auto_approve" ? "Always allow" : "Always deny";
|
|
85
|
+
const evidence = s.kind === "auto_approve" ? `approved ${s.evidenceApproved}/${s.evidenceApproved + s.evidenceDenied} over ${s.windowDays}d` : `denied ${s.evidenceDenied}/${s.evidenceApproved + s.evidenceDenied} over ${s.windowDays}d`;
|
|
86
|
+
console.log(` ${cyan(s.toolPattern)} ${dim(s.id)}`);
|
|
87
|
+
console.log(` ${verb} \u2014 ${evidence}`);
|
|
88
|
+
console.log(` ${dim(`pushary suggestions accept ${s.id}`)}
|
|
89
|
+
`);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
main().catch((err) => {
|
|
93
|
+
if (err instanceof UsageError) {
|
|
94
|
+
process.stderr.write(` ! ${err.message}
|
|
95
|
+
`);
|
|
96
|
+
process.exit(EXIT.USAGE);
|
|
97
|
+
}
|
|
98
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
99
|
+
process.exit(1);
|
|
100
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
registerTranscript
|
|
4
|
+
} from "../chunk-JZTHGAPA.js";
|
|
5
|
+
import "../chunk-SGZJ5LYH.js";
|
|
6
|
+
import "../chunk-EYK3GSRH.js";
|
|
7
|
+
import "../chunk-ZVSKMPBZ.js";
|
|
8
|
+
import "../chunk-C2WCPBF7.js";
|
|
9
|
+
import "../chunk-6J2JC2RT.js";
|
|
10
|
+
import "../chunk-WE2J62NC.js";
|
|
11
|
+
import "../chunk-3EVPNIBE.js";
|
|
12
|
+
import "../chunk-OKXS7WDZ.js";
|
|
13
|
+
import "../chunk-MPWXGONV.js";
|
|
14
|
+
import "../chunk-SAXBC4AZ.js";
|
|
15
|
+
import "../chunk-OLQRRFBX.js";
|
|
16
|
+
import "../chunk-XHKBHWLX.js";
|
|
17
|
+
import "../chunk-EPCXUP3P.js";
|
|
18
|
+
import "../chunk-GMXKITVA.js";
|
|
19
|
+
import "../chunk-P7WQEVWA.js";
|
|
20
|
+
import "../chunk-LXQ5FBBD.js";
|
|
21
|
+
import "../chunk-7QLSKOSU.js";
|
|
22
|
+
import "../chunk-KZERVKTD.js";
|
|
23
|
+
import "../chunk-DB3ONZB4.js";
|
|
24
|
+
import "../chunk-A2A2YTMG.js";
|
|
25
|
+
import "../chunk-T7E75EKA.js";
|
|
26
|
+
import "../chunk-GPEGOGRJ.js";
|
|
27
|
+
import "../chunk-E4FJTUH4.js";
|
|
28
|
+
import "../chunk-NQTHFF4W.js";
|
|
29
|
+
|
|
30
|
+
// bin/pushary-transcript-register.ts
|
|
31
|
+
var raw = "";
|
|
32
|
+
for await (const chunk of process.stdin) {
|
|
33
|
+
raw += chunk;
|
|
34
|
+
if (raw.length > 1024 * 1024) process.exit(0);
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const input = JSON.parse(raw);
|
|
38
|
+
if (input && typeof input === "object" && !Array.isArray(input)) registerTranscript(process.argv[2] ?? "", input, void 0, { siteId: process.argv[3], baseUrl: process.argv[4] });
|
|
39
|
+
} catch {
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
clearPin,
|
|
4
|
+
fingerprint,
|
|
5
|
+
loadPin
|
|
6
|
+
} from "../chunk-SGZJ5LYH.js";
|
|
7
|
+
import {
|
|
8
|
+
transcriptsEnabled
|
|
9
|
+
} from "../chunk-OLQRRFBX.js";
|
|
10
|
+
import {
|
|
11
|
+
exitOnHelpFlag
|
|
12
|
+
} from "../chunk-HZVVNGEW.js";
|
|
13
|
+
import "../chunk-P7WQEVWA.js";
|
|
14
|
+
import "../chunk-KZERVKTD.js";
|
|
15
|
+
import "../chunk-DB3ONZB4.js";
|
|
16
|
+
import "../chunk-T7E75EKA.js";
|
|
17
|
+
import "../chunk-GPEGOGRJ.js";
|
|
18
|
+
import "../chunk-E4FJTUH4.js";
|
|
19
|
+
import "../chunk-NQTHFF4W.js";
|
|
20
|
+
|
|
21
|
+
// bin/pushary-transcripts.ts
|
|
22
|
+
exitOnHelpFlag("transcripts");
|
|
23
|
+
var dim = (text) => `\x1B[2m${text}\x1B[0m`;
|
|
24
|
+
var bold = (text) => `\x1B[1m${text}\x1B[0m`;
|
|
25
|
+
var showStatus = () => {
|
|
26
|
+
const pin = loadPin();
|
|
27
|
+
console.log();
|
|
28
|
+
console.log(` ${bold("Transcript sync")} ${transcriptsEnabled() ? "on" : dim("off")}`);
|
|
29
|
+
console.log();
|
|
30
|
+
if (!pin) {
|
|
31
|
+
console.log(` No keys pinned yet. The first sync on this machine records the keys it`);
|
|
32
|
+
console.log(` seals to, and every later change has to be accepted here.`);
|
|
33
|
+
console.log();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
console.log(` ${bold("Phone key")} ${fingerprint(pin.phonePublicKey)}`);
|
|
37
|
+
console.log(` ${dim("Compare this with the fingerprint in the app under Settings.")}`);
|
|
38
|
+
console.log();
|
|
39
|
+
if (pin.providerKeyId && pin.providerPublicKey) {
|
|
40
|
+
console.log(` ${bold("Recovery key")} ${pin.providerKeyId.slice(0, 16)}`);
|
|
41
|
+
console.log(` ${dim("Pushary can recover a session sealed to this key under a documented")}`);
|
|
42
|
+
console.log(` ${dim("legal obligation. Sessions sealed before it existed cannot be recovered.")}`);
|
|
43
|
+
} else {
|
|
44
|
+
console.log(` ${bold("Recovery key")} ${dim("none")}`);
|
|
45
|
+
console.log(` ${dim("Only your phone can read these transcripts. Nobody at Pushary can.")}`);
|
|
46
|
+
}
|
|
47
|
+
console.log();
|
|
48
|
+
};
|
|
49
|
+
var rotate = () => {
|
|
50
|
+
const had = loadPin();
|
|
51
|
+
clearPin();
|
|
52
|
+
console.log();
|
|
53
|
+
if (!had) {
|
|
54
|
+
console.log(` Nothing was pinned. The next sync records whatever the server offers.`);
|
|
55
|
+
} else {
|
|
56
|
+
console.log(` Dropped the pinned keys. The next sync records what the server offers now`);
|
|
57
|
+
console.log(` and resumes uploading.`);
|
|
58
|
+
console.log();
|
|
59
|
+
console.log(` ${dim("If you did not reinstall the app or rotate a key, stop and check with")}`);
|
|
60
|
+
console.log(` ${dim("Pushary before running an agent on this machine.")}`);
|
|
61
|
+
}
|
|
62
|
+
console.log();
|
|
63
|
+
};
|
|
64
|
+
var args = process.argv.slice(2);
|
|
65
|
+
var wantsRotate = args.includes("--rotate");
|
|
66
|
+
var verb = args.find((arg) => !arg.startsWith("-"));
|
|
67
|
+
if (verb === "trust" && wantsRotate) {
|
|
68
|
+
rotate();
|
|
69
|
+
} else if (verb === "trust") {
|
|
70
|
+
console.error(`Run \`pushary transcripts trust --rotate\` to accept the keys the server is offering now.`);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
} else if (verb === void 0 || verb === "status") {
|
|
73
|
+
showStatus();
|
|
74
|
+
} else {
|
|
75
|
+
console.error(`Unknown: ${verb}. Try \`pushary transcripts status\` or \`pushary transcripts trust --rotate\`.`);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|