@getrift/rift 0.1.0-beta.13 → 0.1.0-beta.15
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 +35 -9
- package/dist/src/capture/observability.d.ts +36 -0
- package/dist/src/capture/observability.d.ts.map +1 -1
- package/dist/src/capture/observability.js +42 -4
- package/dist/src/capture/observability.js.map +1 -1
- package/dist/src/cli/commands/capture.d.ts.map +1 -1
- package/dist/src/cli/commands/capture.js +25 -0
- package/dist/src/cli/commands/capture.js.map +1 -1
- package/dist/src/cli/commands/doctor.d.ts +6 -0
- package/dist/src/cli/commands/doctor.d.ts.map +1 -0
- package/dist/src/cli/commands/doctor.js +183 -0
- package/dist/src/cli/commands/doctor.js.map +1 -0
- package/dist/src/cli/commands/menubar.d.ts +30 -0
- package/dist/src/cli/commands/menubar.d.ts.map +1 -0
- package/dist/src/cli/commands/menubar.js +180 -0
- package/dist/src/cli/commands/menubar.js.map +1 -0
- package/dist/src/cli/commands/onboard.d.ts.map +1 -1
- package/dist/src/cli/commands/onboard.js +71 -31
- package/dist/src/cli/commands/onboard.js.map +1 -1
- package/dist/src/cli/commands/status.d.ts +9 -7
- package/dist/src/cli/commands/status.d.ts.map +1 -1
- package/dist/src/cli/commands/status.js +29 -10
- package/dist/src/cli/commands/status.js.map +1 -1
- package/dist/src/cli/commands/update.d.ts +3 -0
- package/dist/src/cli/commands/update.d.ts.map +1 -1
- package/dist/src/cli/commands/update.js +19 -0
- package/dist/src/cli/commands/update.js.map +1 -1
- package/dist/src/cli/index.d.ts.map +1 -1
- package/dist/src/cli/index.js +4 -0
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/postinstall-menubar.d.ts +22 -0
- package/dist/src/cli/postinstall-menubar.d.ts.map +1 -0
- package/dist/src/cli/postinstall-menubar.js +39 -0
- package/dist/src/cli/postinstall-menubar.js.map +1 -0
- package/dist/src/cli/status/friend-header.d.ts.map +1 -1
- package/dist/src/cli/status/friend-header.js +59 -4
- package/dist/src/cli/status/friend-header.js.map +1 -1
- package/dist/src/diagnostics/doctor.d.ts +106 -0
- package/dist/src/diagnostics/doctor.d.ts.map +1 -0
- package/dist/src/diagnostics/doctor.js +282 -0
- package/dist/src/diagnostics/doctor.js.map +1 -0
- package/dist/src/diagnostics/notify.d.ts +90 -0
- package/dist/src/diagnostics/notify.d.ts.map +1 -0
- package/dist/src/diagnostics/notify.js +177 -0
- package/dist/src/diagnostics/notify.js.map +1 -0
- package/dist/src/diagnostics/repair-prompt.d.ts +49 -0
- package/dist/src/diagnostics/repair-prompt.d.ts.map +1 -0
- package/dist/src/diagnostics/repair-prompt.js +198 -0
- package/dist/src/diagnostics/repair-prompt.js.map +1 -0
- package/dist/src/main.js +45 -4
- package/dist/src/main.js.map +1 -1
- package/dist/src/observability/version-check.d.ts +1 -0
- package/dist/src/observability/version-check.d.ts.map +1 -1
- package/dist/src/observability/version-check.js +2 -1
- package/dist/src/observability/version-check.js.map +1 -1
- package/dist/src/server/routes/friend-status.d.ts +25 -0
- package/dist/src/server/routes/friend-status.d.ts.map +1 -1
- package/dist/src/server/routes/friend-status.js +6 -2
- package/dist/src/server/routes/friend-status.js.map +1 -1
- package/operator/swiftbar/render-menu.py +444 -0
- package/operator/swiftbar/rift.10s.sh +152 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -27,6 +27,7 @@ Tout reste sur ta machine, sauf les *embeddings* (envoyés à Voyage AI sous une
|
|
|
27
27
|
| 2 | **Node.js 20.19+** | `node --version` dans Ghostty. Si manquant : [nodejs.org](https://nodejs.org/en/download) (LTS) |
|
|
28
28
|
| 3 | **Codex CLI authentifié** | `codex --version`, puis `codex login` si tu n'as jamais loggé |
|
|
29
29
|
| 4 | **Une clé Voyage AI** | Je te l'envoie en DM (c'est un projet dédié sur mon compte Voyage). Range-la dans 1Password, on la collera pendant l'onboard |
|
|
30
|
+
| 5 | **SwiftBar** | Optionnel mais recommandé pour voir l'état Rift dans la barre de menu. Le script installe le plugin Rift automatiquement ; si l'app manque, ouvre [swiftbar.app](https://swiftbar.app) puis relance `rift menubar install`. |
|
|
30
31
|
|
|
31
32
|
Codex CLI fait tourner le triage et l'extraction de métadonnées — pas besoin de clé OpenAI séparée. La clé Voyage sert *uniquement* aux embeddings.
|
|
32
33
|
|
|
@@ -44,6 +45,7 @@ Ce que fait le script :
|
|
|
44
45
|
- installe le paquet npm `@getrift/rift@beta` globalement ;
|
|
45
46
|
- crée tes dossiers de données sous `~/Library/Application Support/Rift/` ;
|
|
46
47
|
- pose un agent launchd qui lance Rift à chaque session ;
|
|
48
|
+
- installe le plugin Rift pour SwiftBar (menu bar) quand possible ;
|
|
47
49
|
- attend que le daemon réponde sur le port local.
|
|
48
50
|
|
|
49
51
|
**Si on te demande ton mot de passe Mac (`Password:`)**, c'est normal — il faut écrire dans un dossier système pour rendre la commande `rift` disponible partout. Tape ton mot de passe (rien ne s'affiche pendant la frappe — c'est normal sur Unix), `Entrée`.
|
|
@@ -56,18 +58,37 @@ Si ça plante en cours de route, le script restaure ton état précédent et imp
|
|
|
56
58
|
rift onboard
|
|
57
59
|
```
|
|
58
60
|
|
|
59
|
-
L'assistant
|
|
61
|
+
L'assistant t'explique d'abord ce qui reste local et ce qui sort (les *embeddings* vers Voyage), **puis** te guide dans l'ordre réel du wizard :
|
|
60
62
|
|
|
61
|
-
1. **La clé Voyage que je t'ai envoyée.** Colle-la depuis 1Password
|
|
62
|
-
2. **Validation.** Rift fait un embed test pour vérifier la cl
|
|
63
|
+
1. **La clé Voyage que je t'ai envoyée.** L'assistant rappelle à quoi elle sert avant de la demander. Colle-la depuis 1Password — elle ne s'affiche pas pendant la frappe.
|
|
64
|
+
2. **Validation.** Rift fait un embed test pour vérifier la clé, la stocke localement, puis redémarre le service.
|
|
63
65
|
3. **Vérifie que Codex est authentifié.** Si ça échoue, lance `codex login` et relance `rift onboard`. Ou demande à Claude.
|
|
64
|
-
4. **
|
|
65
|
-
5. **
|
|
66
|
+
4. **Sessions détectées.** Rift compte tes sessions Claude Code et Codex CLI existantes.
|
|
67
|
+
5. **Feedback.** Par défaut, les notes restent dans un fichier local JSONL ; le relais n'est activé que via un flag opérateur.
|
|
66
68
|
6. **Garde-fou Claude Code (optionnel).** Si Claude Code est détecté, l'assistant te propose d'installer un *PreToolUse hook* qui force la récupération Rift à commencer par `rift_context_pack` (compact, budgété) avant tout `rift_search`. Évite que l'agent crame ton contexte avec des recherches larges. **Réponds `y`** si tu utilises Claude Code. Désactivable à tout moment via `RIFT_POLICY_DISABLED=1` ou en supprimant l'entrée de `~/.claude/settings.json`.
|
|
69
|
+
7. **Première passe de capture.** Watermarke tes sessions existantes (ne les ingère pas).
|
|
70
|
+
8. **Import optionnel.** L'assistant te propose de déposer un export ChatGPT à importer maintenant (ou `skip`). **Pour la beta : `skip`** — voir la section payante plus bas.
|
|
71
|
+
|
|
72
|
+
> L'onboarding **ne branche aucun client MCP tout seul** et ne te demande pas lesquels connecter. C'est une étape séparée, à faire après l'onboarding (voir juste en dessous).
|
|
67
73
|
|
|
68
74
|
À la fin, l'assistant te dit "Onboarding terminé" et te suggère ta première recherche.
|
|
69
75
|
|
|
70
|
-
|
|
76
|
+
### Brancher Rift à tes apps (MCP)
|
|
77
|
+
|
|
78
|
+
L'onboarding installe et indexe Rift, mais ne le connecte à aucune app. Fais-le ensuite, app par app, avec une commande non-interactive :
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
rift mcp install --client=claude-desktop
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Clients supportés (`--client <id>`) :
|
|
85
|
+
|
|
86
|
+
- `claude-desktop` — l'app Claude pour Mac
|
|
87
|
+
- `claude-code` — l'outil Claude Code en terminal
|
|
88
|
+
- `cursor` — l'éditeur Cursor
|
|
89
|
+
- `codex` — l'outil Codex en terminal
|
|
90
|
+
|
|
91
|
+
Pour tout brancher d'un coup : `rift mcp install --all`. Il faut passer `--client <id>` ou `--all` — sans l'un des deux, la commande s'arrête.
|
|
71
92
|
|
|
72
93
|
> Si tu as déjà fait `rift onboard` avant cette beta, tu peux poser le hook après coup avec `rift hooks install --client claude-code`.
|
|
73
94
|
|
|
@@ -92,18 +113,21 @@ Next: nothing broken. Try rift search "<topic>".
|
|
|
92
113
|
|
|
93
114
|
Les ✓ partout = tout va bien. Si une ligne montre ✗ ou un *Next:* différent de "nothing broken", suis l'instruction qu'il imprime.
|
|
94
115
|
|
|
116
|
+
> La ligne `MCP:` reflète les clients que **tu** as branchés avec `rift mcp install` — l'onboarding n'en connecte aucun automatiquement. Juste après l'onboarding, tu peux n'avoir aucun ✓ ici tant que tu n'as pas lancé cette commande.
|
|
117
|
+
|
|
95
118
|
## Usage quotidien
|
|
96
119
|
|
|
97
|
-
- **Rien à faire.** Le daemon tourne en tâche de fond, ingère tes nouvelles sessions Claude Code / Codex CLI toutes les heures,
|
|
120
|
+
- **Rien à faire.** Le daemon tourne en tâche de fond, ingère tes nouvelles sessions Claude Code / Codex CLI toutes les heures, expose la mémoire via MCP, et le menu bar Rift te montre si tout va bien.
|
|
98
121
|
- **Tester depuis Claude Desktop ou Cursor.** Ouvre une conversation, demande par exemple : *"Rappelle-toi ce qu'on a discuté sur le pricing la semaine dernière, va voir dans Rift"* — Claude/Cursor appellera `rift_search` ou `rift_context_pack` automatiquement et t'affichera ce qu'il trouve.
|
|
99
122
|
- **Rechercher en ligne de commande :** `rift search "comment on a structuré le pricing"`
|
|
100
123
|
- **Forcer une passe de capture maintenant :** `rift capture`
|
|
124
|
+
- **Mettre à jour :** Rift vérifie le tag beta toutes les heures. Si une nouvelle version existe, `rift status`, `rift doctor` et le menu bar affichent `rift update` ; dans le menu bar, clique **Update Rift**.
|
|
101
125
|
|
|
102
126
|
## Vie privée
|
|
103
127
|
|
|
104
128
|
- **Local par défaut.** Tes sessions, métadonnées et la base vectorielle (LanceDB) restent sur ta machine.
|
|
105
129
|
- **Voyage AI.** Seuls les *snippets* envoyés pour embedding partent vers Voyage. Ta clé t'appartient — tu peux la révoquer côté Voyage à tout moment, ce qui coupe l'envoi.
|
|
106
|
-
- **Aucune télémétrie de contenu.** Rift ne m'envoie rien
|
|
130
|
+
- **Aucune télémétrie de contenu.** Rift ne m'envoie rien. La commande `rift feedback --kind=...` écrit ta note dans un JSONL local — elle ne part nulle part. Le *feedback relay* (envoi de la note à Clem) n'existe pas par défaut : il faut le configurer explicitement pendant l'onboarding via `rift onboard --enable-feedback-relay <url>`, et même activé, il ne transmet que la note que tu écris, jamais tes conversations.
|
|
107
131
|
- **Désinstallation propre.** `rift uninstall` enlève le daemon et les entrées MCP. `rift uninstall --purge-data` supprime aussi les données locales.
|
|
108
132
|
|
|
109
133
|
Le contrat de vie privée détaillé est dans `docs/feedback/PRIVACY.md` (livré avec le paquet).
|
|
@@ -136,9 +160,11 @@ Pour déclencher : il me faut un **bon de commande / facture HT signée** par to
|
|
|
136
160
|
| `rift status` dit "daemon: unreachable" | `launchctl kickstart -k gui/$UID/com.getrift.daemon` |
|
|
137
161
|
| Codex CLI auth périmé | `codex login` |
|
|
138
162
|
| Clé Voyage révoquée ou changée | `rift onboard --reconfigure-voyage` |
|
|
163
|
+
| Le menu bar Rift n'apparaît pas | Ouvre SwiftBar, puis lance `rift menubar install` |
|
|
164
|
+
| Une mise à jour est disponible | `rift update` |
|
|
139
165
|
| Rift n'apparaît pas dans Claude Desktop / Cursor | `rift mcp install --client=claude-desktop` (remplace par `codex`, `claude-code`, `cursor` selon le besoin) |
|
|
140
166
|
| Le garde-fou Claude Code te bloque trop souvent | `export RIFT_POLICY_DISABLED=1` dans le shell (désactive le hook le temps de la session), ou enlève l'entrée `rift-policy.mjs` de `~/.claude/settings.json` |
|
|
141
|
-
| Truc bizarre, tu veux me prévenir | `rift feedback --kind=broke --with-status` — capture l'état actuel et
|
|
167
|
+
| Truc bizarre, tu veux me prévenir | `rift feedback --kind=broke --with-status` — capture l'état actuel et l'écrit en local (JSONL). Envoie-moi le fichier, ou copie-colle. |
|
|
142
168
|
|
|
143
169
|
## Désinstaller
|
|
144
170
|
|
|
@@ -6,6 +6,17 @@ export interface AutoCaptureRunError {
|
|
|
6
6
|
source?: AutoCaptureSource;
|
|
7
7
|
error: string;
|
|
8
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Who initiated a capture run. `daemon` = the scheduled hourly loop;
|
|
11
|
+
* `manual` = a `rift capture` invocation; `onboard` = the first-capture pass
|
|
12
|
+
* inside `rift onboard`. Only `daemon` runs represent the scheduled loop's
|
|
13
|
+
* health; `manual`/`onboard` are ad-hoc runs that prove "capture works now"
|
|
14
|
+
* without speaking for the daemon. Optional on the record because rows
|
|
15
|
+
* written before this field existed carry no trigger — every reader MUST
|
|
16
|
+
* treat a missing trigger as `daemon` (the daemon was the only writer then).
|
|
17
|
+
* See `summarizeAutoCaptureRuns` here and the friend-status route.
|
|
18
|
+
*/
|
|
19
|
+
export type AutoCaptureTrigger = "daemon" | "manual" | "onboard";
|
|
9
20
|
export interface AutoCaptureRunRecord {
|
|
10
21
|
timestamp: string;
|
|
11
22
|
enabled_sources: AutoCaptureSource[];
|
|
@@ -15,6 +26,8 @@ export interface AutoCaptureRunRecord {
|
|
|
15
26
|
counts_by_source: Partial<Record<AutoCaptureSource, CaptureSourceCounts>>;
|
|
16
27
|
errors: AutoCaptureRunError[];
|
|
17
28
|
run_error?: string;
|
|
29
|
+
/** Who ran this capture. Absent on legacy rows → read as `daemon`. */
|
|
30
|
+
trigger?: AutoCaptureTrigger;
|
|
18
31
|
}
|
|
19
32
|
export interface AutoCaptureSourceSuccess {
|
|
20
33
|
timestamp: string;
|
|
@@ -24,7 +37,15 @@ export interface AutoCaptureSourceSuccess {
|
|
|
24
37
|
new: number;
|
|
25
38
|
}
|
|
26
39
|
export interface AutoCaptureRunSummary {
|
|
40
|
+
/** Newest run of any trigger — drives the "last capture" freshness line. */
|
|
27
41
|
last_run: AutoCaptureRunRecord | null;
|
|
42
|
+
/**
|
|
43
|
+
* Newest run that came from the daemon's scheduled loop (legacy untagged
|
|
44
|
+
* rows count as daemon). Tracked separately from `last_run` so a manual
|
|
45
|
+
* success can refresh status WITHOUT laundering a still-failing scheduled
|
|
46
|
+
* loop: the daemon's own health stays observable here.
|
|
47
|
+
*/
|
|
48
|
+
last_daemon_run: AutoCaptureRunRecord | null;
|
|
28
49
|
last_success_by_source: Partial<Record<AutoCaptureSource, AutoCaptureSourceSuccess | null>>;
|
|
29
50
|
}
|
|
30
51
|
export declare function autoCaptureRunsPath(dataDir: string): string;
|
|
@@ -33,9 +54,24 @@ export declare function buildAutoCaptureRunRecord(opts: {
|
|
|
33
54
|
enabledSources: AutoCaptureSource[];
|
|
34
55
|
durationMs: number;
|
|
35
56
|
report: CaptureReport;
|
|
57
|
+
/** Daemon loop vs. a manual `rift capture`. */
|
|
58
|
+
trigger: AutoCaptureTrigger;
|
|
36
59
|
}): AutoCaptureRunRecord;
|
|
37
60
|
export declare function appendAutoCaptureRunRecord(dataDir: string, record: AutoCaptureRunRecord, maxLines?: number): Promise<void>;
|
|
38
61
|
export declare function readAutoCaptureRunRecords(dataDir: string): AutoCaptureRunRecord[];
|
|
62
|
+
/**
|
|
63
|
+
* Whether a recorded run failed, across ALL three failure shapes:
|
|
64
|
+
* - `run_ok: false` — the loop threw (daemon catch-all path).
|
|
65
|
+
* - `preflight_ok: false` — e.g. an expired `codex login`. Recorded with
|
|
66
|
+
* `run_ok: true` because the run completed; this is the COMMON real
|
|
67
|
+
* failure, so a `run_ok`-only check would miss it and let a manual
|
|
68
|
+
* success launder the daemon green.
|
|
69
|
+
* - `errors.length > 0` — the run completed but hit per-session errors.
|
|
70
|
+
* Mirrors how diagnostics treats a live capture as broken
|
|
71
|
+
* (`last_errors > 0` OR `codex.last_preflight_ok === false`), so the
|
|
72
|
+
* daemon's own latest outcome is judged by the same bar.
|
|
73
|
+
*/
|
|
74
|
+
export declare function autoCaptureRunFailed(record: AutoCaptureRunRecord): boolean;
|
|
39
75
|
export declare function summarizeAutoCaptureRuns(records: AutoCaptureRunRecord[], sources?: AutoCaptureSource[]): AutoCaptureRunSummary;
|
|
40
76
|
export declare function readAutoCaptureRunSummary(dataDir: string, sources?: AutoCaptureSource[]): AutoCaptureRunSummary;
|
|
41
77
|
export declare function formatAutoCaptureSummary(summary: AutoCaptureRunSummary): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../../../src/capture/observability.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACpB,MAAM,mBAAmB,CAAC;AAG3B,eAAO,MAAM,sBAAsB,4BAA4B,CAAC;AAChE,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAEhD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,iBAAiB,EAAE,CAAC;IACrC,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAC1E,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../../../src/capture/observability.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACpB,MAAM,mBAAmB,CAAC;AAG3B,eAAO,MAAM,sBAAsB,4BAA4B,CAAC;AAChE,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAEhD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEjE,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,iBAAiB,EAAE,CAAC;IACrC,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAC1E,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,qBAAqB;IACpC,4EAA4E;IAC5E,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtC;;;;;OAKG;IACH,eAAe,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC7C,sBAAsB,EAAE,OAAO,CAC7B,MAAM,CAAC,iBAAiB,EAAE,wBAAwB,GAAG,IAAI,CAAC,CAC3D,CAAC;CACH;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,iBAAiB,EAAE,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,aAAa,CAAC;IACtB,+CAA+C;IAC/C,OAAO,EAAE,kBAAkB,CAAC;CAC7B,GAAG,oBAAoB,CAmBvB;AAED,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,oBAAoB,EAC5B,QAAQ,SAA8B,GACrC,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,GACd,oBAAoB,EAAE,CAQxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAE1E;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,oBAAoB,EAAE,EAC/B,OAAO,GAAE,iBAAiB,EAAiC,GAC1D,qBAAqB,CAyCvB;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,iBAAiB,EAAiC,GAC1D,qBAAqB,CAEvB;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAW/E"}
|
|
@@ -11,8 +11,10 @@ export function buildAutoCaptureRunRecord(opts) {
|
|
|
11
11
|
return {
|
|
12
12
|
timestamp: opts.timestamp,
|
|
13
13
|
enabled_sources: opts.enabledSources,
|
|
14
|
-
// If runAutoCapture returned a report, the run completed.
|
|
15
|
-
//
|
|
14
|
+
// If runAutoCapture returned a report, the run completed. run_ok: false
|
|
15
|
+
// is only written by the daemon's catch-all path (a thrown run); both
|
|
16
|
+
// the daemon and the manual command reach this builder on a completed
|
|
17
|
+
// run, distinguished by `trigger`.
|
|
16
18
|
run_ok: true,
|
|
17
19
|
preflight_ok: opts.report.preflight_ok,
|
|
18
20
|
duration_ms: opts.durationMs,
|
|
@@ -22,12 +24,18 @@ export function buildAutoCaptureRunRecord(opts) {
|
|
|
22
24
|
...(err.source ? { source: err.source } : {}),
|
|
23
25
|
error: err.error,
|
|
24
26
|
})),
|
|
27
|
+
trigger: opts.trigger,
|
|
25
28
|
};
|
|
26
29
|
}
|
|
27
30
|
export async function appendAutoCaptureRunRecord(dataDir, record, maxLines = AUTO_CAPTURE_RUNS_MAX_LINES) {
|
|
28
31
|
const filePath = autoCaptureRunsPath(dataDir);
|
|
29
|
-
//
|
|
30
|
-
//
|
|
32
|
+
// Two writers now: the daemon's scheduled loop and a manual `rift capture`
|
|
33
|
+
// (tagged via `record.trigger`). The final write is atomic, but the
|
|
34
|
+
// read/modify/write is not locked, so a daemon tick firing in the exact
|
|
35
|
+
// same window as a manual run could drop one row. That's an acceptable
|
|
36
|
+
// loss for an append-only health log (no correctness impact, just a
|
|
37
|
+
// missed observability line) and far cheaper than a file lock; revisit
|
|
38
|
+
// only if a third concurrent writer appears.
|
|
31
39
|
const lines = fs.existsSync(filePath)
|
|
32
40
|
? fs.readFileSync(filePath, "utf-8").split("\n").filter(Boolean)
|
|
33
41
|
: [];
|
|
@@ -45,6 +53,21 @@ export function readAutoCaptureRunRecords(dataDir) {
|
|
|
45
53
|
.filter(Boolean)
|
|
46
54
|
.map((line) => JSON.parse(line));
|
|
47
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Whether a recorded run failed, across ALL three failure shapes:
|
|
58
|
+
* - `run_ok: false` — the loop threw (daemon catch-all path).
|
|
59
|
+
* - `preflight_ok: false` — e.g. an expired `codex login`. Recorded with
|
|
60
|
+
* `run_ok: true` because the run completed; this is the COMMON real
|
|
61
|
+
* failure, so a `run_ok`-only check would miss it and let a manual
|
|
62
|
+
* success launder the daemon green.
|
|
63
|
+
* - `errors.length > 0` — the run completed but hit per-session errors.
|
|
64
|
+
* Mirrors how diagnostics treats a live capture as broken
|
|
65
|
+
* (`last_errors > 0` OR `codex.last_preflight_ok === false`), so the
|
|
66
|
+
* daemon's own latest outcome is judged by the same bar.
|
|
67
|
+
*/
|
|
68
|
+
export function autoCaptureRunFailed(record) {
|
|
69
|
+
return !record.run_ok || !record.preflight_ok || record.errors.length > 0;
|
|
70
|
+
}
|
|
48
71
|
export function summarizeAutoCaptureRuns(records, sources = DEFAULT_AUTO_CAPTURE_SOURCES) {
|
|
49
72
|
const lastSuccess = {};
|
|
50
73
|
for (const source of sources) {
|
|
@@ -66,8 +89,23 @@ export function summarizeAutoCaptureRuns(records, sources = DEFAULT_AUTO_CAPTURE
|
|
|
66
89
|
};
|
|
67
90
|
}
|
|
68
91
|
}
|
|
92
|
+
// Walk back to the newest daemon-triggered (or legacy untagged) run. This
|
|
93
|
+
// is what keeps an ad-hoc success from masking a failing scheduled loop:
|
|
94
|
+
// `last_run` reflects the freshest capture of any kind, while this stays
|
|
95
|
+
// pinned to the daemon's own latest outcome. `manual` AND `onboard` runs
|
|
96
|
+
// are ad-hoc and excluded here — only `daemon` (or a legacy untagged row,
|
|
97
|
+
// written when the daemon was the sole writer) speaks for the loop.
|
|
98
|
+
let lastDaemonRun = null;
|
|
99
|
+
for (let i = records.length - 1; i >= 0; i--) {
|
|
100
|
+
const record = records[i];
|
|
101
|
+
if (record && (record.trigger === "daemon" || record.trigger === undefined)) {
|
|
102
|
+
lastDaemonRun = record;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
69
106
|
return {
|
|
70
107
|
last_run: records.at(-1) ?? null,
|
|
108
|
+
last_daemon_run: lastDaemonRun,
|
|
71
109
|
last_success_by_source: lastSuccess,
|
|
72
110
|
};
|
|
73
111
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observability.js","sourceRoot":"","sources":["../../../src/capture/observability.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAMnD,OAAO,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAE5D,MAAM,CAAC,MAAM,sBAAsB,GAAG,yBAAyB,CAAC;AAChE,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"observability.js","sourceRoot":"","sources":["../../../src/capture/observability.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoBpC,wBAAgB,kBAAkB,IAAI,OAAO,CAqL5C"}
|
|
@@ -12,6 +12,7 @@ import { createHttpClient, readToken, resolveBaseUrl, CliError, requireExistingC
|
|
|
12
12
|
import { pollJob } from "../job-poller.js";
|
|
13
13
|
import { isJobFailure } from "../output.js";
|
|
14
14
|
import { runAutoCapture, resolveCodexCaptureDeps, } from "../../capture/auto-capture.js";
|
|
15
|
+
import { appendAutoCaptureRunRecord, buildAutoCaptureRunRecord, } from "../../capture/observability.js";
|
|
15
16
|
import { makeCaptureRecoverCommand } from "./capture-recover.js";
|
|
16
17
|
export function makeCaptureCommand() {
|
|
17
18
|
const cmd = new Command("capture")
|
|
@@ -47,6 +48,7 @@ export function makeCaptureCommand() {
|
|
|
47
48
|
: (() => {
|
|
48
49
|
throw new CliError("Invalid --source. Use claude_code or codex_cli.", "validation");
|
|
49
50
|
})();
|
|
51
|
+
const startedAt = new Date();
|
|
50
52
|
const report = await runAutoCapture({
|
|
51
53
|
dataDir,
|
|
52
54
|
claudeDir: opts.claudeDir,
|
|
@@ -81,6 +83,29 @@ export function makeCaptureCommand() {
|
|
|
81
83
|
}
|
|
82
84
|
},
|
|
83
85
|
});
|
|
86
|
+
// Record this manual run in the same health ledger the daemon
|
|
87
|
+
// writes, tagged `manual`, so `rift status` / `rift doctor` reflect
|
|
88
|
+
// the fresh capture immediately instead of the daemon's last row.
|
|
89
|
+
// Dry-runs change nothing, so they never write. Best-effort: a
|
|
90
|
+
// ledger-append failure must not make a successful capture look
|
|
91
|
+
// broken (mirrors the daemon's own append guard in main.ts).
|
|
92
|
+
if (!opts.dryRun) {
|
|
93
|
+
try {
|
|
94
|
+
const enabledSources = source ? [source] : config.capture.sources;
|
|
95
|
+
await appendAutoCaptureRunRecord(dataDir, buildAutoCaptureRunRecord({
|
|
96
|
+
timestamp: startedAt.toISOString(),
|
|
97
|
+
enabledSources,
|
|
98
|
+
durationMs: Date.now() - startedAt.getTime(),
|
|
99
|
+
report,
|
|
100
|
+
trigger: "manual",
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
103
|
+
catch (observabilityErr) {
|
|
104
|
+
process.stderr.write(`Capture run-record append failed: ${observabilityErr instanceof Error
|
|
105
|
+
? observabilityErr.message
|
|
106
|
+
: String(observabilityErr)}\n`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
84
109
|
// Output report
|
|
85
110
|
if (globalOpts.json) {
|
|
86
111
|
process.stdout.write(JSON.stringify(report, null, 2) + "\n");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../../../../src/cli/commands/capture.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../../../../src/cli/commands/capture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { type DoctorReport } from "../../diagnostics/doctor.js";
|
|
3
|
+
export declare function makeDoctorCommand(): Command;
|
|
4
|
+
/** Render the human-readable diagnosis. */
|
|
5
|
+
export declare function renderReport(report: DoctorReport): string[];
|
|
6
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,6BAA6B,CAAC;AAOrC,wBAAgB,iBAAiB,IAAI,OAAO,CA2E3C;AA6DD,2CAA2C;AAC3C,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,CAqC3D"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `rift doctor` — plain-language health diagnosis and repair.
|
|
3
|
+
*
|
|
4
|
+
* Reuses exactly the inputs `rift status` uses (the `/status/friend`
|
|
5
|
+
* payload + local signals) and runs them through the shared `diagnose()`
|
|
6
|
+
* layer, so the two commands never disagree. `rift status` stays the
|
|
7
|
+
* source of truth; `rift doctor` is the "explain what's broken and give
|
|
8
|
+
* me one next action" surface on top of it.
|
|
9
|
+
*
|
|
10
|
+
* rift doctor → plain-language diagnosis
|
|
11
|
+
* rift doctor --json → structured report
|
|
12
|
+
* rift doctor --copy-prompt → redacted repair prompt (Claude)
|
|
13
|
+
* rift doctor --copy-prompt --target=codex
|
|
14
|
+
*
|
|
15
|
+
* With --copy-prompt the prompt is copied to the clipboard (best-effort
|
|
16
|
+
* pbcopy) AND printed to stdout, so it is usable even when the clipboard
|
|
17
|
+
* is unavailable.
|
|
18
|
+
*/
|
|
19
|
+
import { execFileSync } from "node:child_process";
|
|
20
|
+
import { Command } from "commander";
|
|
21
|
+
import { createHttpClient, readToken, resolveBaseUrl, CliError, } from "../http-client.js";
|
|
22
|
+
import { printError, printJson, printText } from "../output.js";
|
|
23
|
+
import { readLocalSignals } from "../status/local-signals.js";
|
|
24
|
+
import { diagnose, } from "../../diagnostics/doctor.js";
|
|
25
|
+
import { buildRepairPrompt, } from "../../diagnostics/repair-prompt.js";
|
|
26
|
+
export function makeDoctorCommand() {
|
|
27
|
+
return new Command("doctor")
|
|
28
|
+
.description("Diagnose Rift in plain language and show one next action")
|
|
29
|
+
.option("--copy-prompt", "Generate a redacted repair prompt to paste into an AI assistant")
|
|
30
|
+
.option("--target <assistant>", "Assistant the repair prompt addresses: claude | codex", "claude")
|
|
31
|
+
.action(async (opts, cmd) => {
|
|
32
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
33
|
+
try {
|
|
34
|
+
const target = normalizeTarget(opts.target);
|
|
35
|
+
const { status, unreachableReason } = await fetchFriendStatus(globalOpts.config);
|
|
36
|
+
const localSignals = readLocalSignals();
|
|
37
|
+
const report = diagnose({
|
|
38
|
+
status,
|
|
39
|
+
...(unreachableReason ? { unreachableReason } : {}),
|
|
40
|
+
localSignals,
|
|
41
|
+
now: Date.now(),
|
|
42
|
+
});
|
|
43
|
+
if (opts.copyPrompt) {
|
|
44
|
+
const prompt = buildRepairPrompt({ report, status, localSignals }, target);
|
|
45
|
+
const copied = copyToClipboard(prompt);
|
|
46
|
+
if (globalOpts.json) {
|
|
47
|
+
printJson({ target, copied_to_clipboard: copied, prompt });
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
printText(copied
|
|
51
|
+
? `Repair prompt for ${target} copied to clipboard. Paste it into ${target}:`
|
|
52
|
+
: `Repair prompt for ${target} (clipboard unavailable — copy it manually):`);
|
|
53
|
+
printText("");
|
|
54
|
+
printText(prompt);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Broken state → non-zero exit so scripts/menus can branch on
|
|
58
|
+
// it. Set this BEFORE any early return so --json and the human
|
|
59
|
+
// path agree on the exit code (a script reading --json must not
|
|
60
|
+
// see "healthy": false alongside a success status).
|
|
61
|
+
if (!report.healthy)
|
|
62
|
+
process.exitCode = 1;
|
|
63
|
+
if (globalOpts.json) {
|
|
64
|
+
printJson(report);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
for (const line of renderReport(report))
|
|
68
|
+
printText(line);
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
if (err instanceof CliError) {
|
|
72
|
+
printError(err.message);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
printError(err instanceof Error ? err.message : String(err));
|
|
76
|
+
}
|
|
77
|
+
process.exitCode = 1;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function normalizeTarget(raw) {
|
|
82
|
+
const value = (raw ?? "claude").toLowerCase();
|
|
83
|
+
if (value === "claude" || value === "codex")
|
|
84
|
+
return value;
|
|
85
|
+
throw new CliError(`Unknown --target "${raw}". Use --target=claude or --target=codex.`, "invalid");
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Fetch `/status/friend`, classifying *why* it failed when it does. A
|
|
89
|
+
* null payload is a valid diagnosis input, but the reason matters: a
|
|
90
|
+
* down daemon, a missing config, and a rejected token each need a
|
|
91
|
+
* different next action, so we never collapse them all into "daemon
|
|
92
|
+
* unreachable" (that would tell a friend to restart a daemon when the
|
|
93
|
+
* real fix is `rift token issue` or `rift onboard`).
|
|
94
|
+
*/
|
|
95
|
+
async function fetchFriendStatus(configPath) {
|
|
96
|
+
let baseUrl;
|
|
97
|
+
try {
|
|
98
|
+
baseUrl = resolveBaseUrl(configPath);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// resolveBaseUrl only throws when the config is absent or invalid.
|
|
102
|
+
return { status: null, unreachableReason: "config_missing" };
|
|
103
|
+
}
|
|
104
|
+
let token;
|
|
105
|
+
try {
|
|
106
|
+
token = await readToken();
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// A locked Keychain etc. — an auth-side failure, not a dead daemon.
|
|
110
|
+
return { status: null, unreachableReason: "auth_failed" };
|
|
111
|
+
}
|
|
112
|
+
if (!token)
|
|
113
|
+
return { status: null, unreachableReason: "not_authenticated" };
|
|
114
|
+
try {
|
|
115
|
+
const client = createHttpClient({ baseUrl, token });
|
|
116
|
+
const data = await client.get("/status/friend");
|
|
117
|
+
return { status: data };
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
return { status: null, unreachableReason: classifyFetchError(err) };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** Map a request failure to the diagnosis reason it implies. */
|
|
124
|
+
function classifyFetchError(err) {
|
|
125
|
+
if (err instanceof CliError) {
|
|
126
|
+
if (err.code === "connection_refused")
|
|
127
|
+
return "connection_refused";
|
|
128
|
+
if (err.code === "unauthorized")
|
|
129
|
+
return "auth_failed";
|
|
130
|
+
}
|
|
131
|
+
return "unknown";
|
|
132
|
+
}
|
|
133
|
+
/** Render the human-readable diagnosis. */
|
|
134
|
+
export function renderReport(report) {
|
|
135
|
+
const lines = [];
|
|
136
|
+
if (report.issues.length === 0) {
|
|
137
|
+
lines.push("Rift is working. Nothing needs attention.");
|
|
138
|
+
return lines;
|
|
139
|
+
}
|
|
140
|
+
const broken = report.issues.filter((i) => i.severity === "broken");
|
|
141
|
+
const warnings = report.issues.filter((i) => i.severity === "warning");
|
|
142
|
+
if (broken.length > 0) {
|
|
143
|
+
lines.push("Rift needs attention.");
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
lines.push("Rift is working, with a few advisories.");
|
|
147
|
+
}
|
|
148
|
+
lines.push("");
|
|
149
|
+
for (const issue of broken) {
|
|
150
|
+
lines.push(`✗ ${issue.title}`);
|
|
151
|
+
lines.push(` ${issue.detail}`);
|
|
152
|
+
lines.push(` → ${issue.nextAction}`);
|
|
153
|
+
lines.push("");
|
|
154
|
+
}
|
|
155
|
+
for (const issue of warnings) {
|
|
156
|
+
lines.push(`• ${issue.title}`);
|
|
157
|
+
lines.push(` → ${issue.nextAction}`);
|
|
158
|
+
lines.push("");
|
|
159
|
+
}
|
|
160
|
+
if (report.primary) {
|
|
161
|
+
lines.push(`Do this first: ${report.primary.nextAction}`);
|
|
162
|
+
lines.push("");
|
|
163
|
+
lines.push("Want an AI to fix it? Run: rift doctor --copy-prompt --target=claude");
|
|
164
|
+
}
|
|
165
|
+
return lines;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Copy text to the macOS clipboard via pbcopy. Returns true on success,
|
|
169
|
+
* false on any failure (non-macOS, pbcopy missing) — the caller still
|
|
170
|
+
* prints the prompt, so a clipboard miss is never fatal.
|
|
171
|
+
*/
|
|
172
|
+
function copyToClipboard(text) {
|
|
173
|
+
if (process.platform !== "darwin")
|
|
174
|
+
return false;
|
|
175
|
+
try {
|
|
176
|
+
execFileSync("pbcopy", [], { input: text });
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
export declare const SWIFTBAR_PLUGIN_NAME = "rift.10s.sh";
|
|
3
|
+
export declare const SWIFTBAR_RENDERER_NAME = "render-menu.py";
|
|
4
|
+
export interface MenuBarInstallOptions {
|
|
5
|
+
homeDir?: string;
|
|
6
|
+
pluginDir?: string;
|
|
7
|
+
sourceDir?: string;
|
|
8
|
+
packageRoot?: string;
|
|
9
|
+
platform?: NodeJS.Platform;
|
|
10
|
+
copy?: boolean;
|
|
11
|
+
now?: () => Date;
|
|
12
|
+
}
|
|
13
|
+
export interface MenuBarInstallResult {
|
|
14
|
+
ok: boolean;
|
|
15
|
+
skipped: boolean;
|
|
16
|
+
reason: string | null;
|
|
17
|
+
pluginDir: string;
|
|
18
|
+
pluginPath: string;
|
|
19
|
+
sourceDir: string | null;
|
|
20
|
+
sourcePath: string | null;
|
|
21
|
+
rendererPath: string | null;
|
|
22
|
+
mode: "symlink" | "copy" | null;
|
|
23
|
+
backupPath: string | null;
|
|
24
|
+
swiftBarDetected: boolean;
|
|
25
|
+
transcript: string[];
|
|
26
|
+
}
|
|
27
|
+
export declare function makeMenuBarCommand(): Command;
|
|
28
|
+
export declare function defaultSwiftBarPluginDir(homeDir?: string): string;
|
|
29
|
+
export declare function installMenuBar(opts?: MenuBarInstallOptions): MenuBarInstallResult;
|
|
30
|
+
//# sourceMappingURL=menubar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menubar.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/menubar.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,oBAAoB,gBAAgB,CAAC;AAClD,eAAO,MAAM,sBAAsB,mBAAmB,CAAC;AAEvD,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAQD,wBAAgB,kBAAkB,IAAI,OAAO,CAoC5C;AAED,wBAAgB,wBAAwB,CAAC,OAAO,SAAe,GAAG,MAAM,CAEvE;AAED,wBAAgB,cAAc,CAC5B,IAAI,GAAE,qBAA0B,GAC/B,oBAAoB,CAwEtB"}
|