@logic-joe/fleek 0.2.14 → 0.2.16
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/fleek.mjs +662 -263
- package/package.json +1 -1
package/dist/fleek.mjs
CHANGED
|
@@ -2395,6 +2395,7 @@ var require_tools = __commonJS({
|
|
|
2395
2395
|
fleek_get_whiteboard: "whiteboards.get",
|
|
2396
2396
|
whiteboard_scene: "whiteboards.get",
|
|
2397
2397
|
fleek_list_attachments: "attachments.list",
|
|
2398
|
+
fleek_get_attachment: "attachments.get",
|
|
2398
2399
|
// DOCFMT stage 1 (DOC-P2) reads, registered in INTEG-4 (coordinator 12.10.2026, IP10 option a)
|
|
2399
2400
|
fleek_read_document_fmd: "documents.readFmd",
|
|
2400
2401
|
fleek_list_space_documents: "documents.listInSpace",
|
|
@@ -4652,7 +4653,7 @@ var require_setup_session = __commonJS({
|
|
|
4652
4653
|
exports.SETUP_SESSION_TTL_MINUTES = 30;
|
|
4653
4654
|
exports.SETUP_SESSION_OPEN_MAX = 10;
|
|
4654
4655
|
exports.SETUP_SESSION_CLAIM_LIMIT = 10;
|
|
4655
|
-
exports.FLEEK_CLI_SETUP_VERSION_DEFAULT = "0.2.
|
|
4656
|
+
exports.FLEEK_CLI_SETUP_VERSION_DEFAULT = "0.2.16";
|
|
4656
4657
|
exports.FLEEK_CLI_PACKAGE = "@logic-joe/fleek";
|
|
4657
4658
|
exports.FLEEK_CANONICAL_SERVER = "https://api.onfleek.app";
|
|
4658
4659
|
exports.SETUP_CLIENT_APPS = ["claude-code", "codex", "orca", "cursor", "other"];
|
|
@@ -5594,7 +5595,7 @@ var require_util = __commonJS({
|
|
|
5594
5595
|
else
|
|
5595
5596
|
target[key] = value;
|
|
5596
5597
|
}
|
|
5597
|
-
function mirrorShape(target, source, keys,
|
|
5598
|
+
function mirrorShape(target, source, keys, wrap2) {
|
|
5598
5599
|
const raw = sourceShape(source);
|
|
5599
5600
|
for (const key of keys) {
|
|
5600
5601
|
const desc = Object.getOwnPropertyDescriptor(raw, key);
|
|
@@ -5603,10 +5604,10 @@ var require_util = __commonJS({
|
|
|
5603
5604
|
if (desc.get) {
|
|
5604
5605
|
deferProp(target, key, () => {
|
|
5605
5606
|
const value = source._zod.def.shape[key];
|
|
5606
|
-
return
|
|
5607
|
+
return wrap2 ? wrap2(value, key) : value;
|
|
5607
5608
|
});
|
|
5608
5609
|
} else
|
|
5609
|
-
putProp(target, key,
|
|
5610
|
+
putProp(target, key, wrap2 ? wrap2(desc.value, key) : desc.value);
|
|
5610
5611
|
}
|
|
5611
5612
|
}
|
|
5612
5613
|
function mirrorProps(target, source) {
|
|
@@ -36471,7 +36472,7 @@ var require_dist2 = __commonJS({
|
|
|
36471
36472
|
var import_types11 = __toESM(require_dist(), 1);
|
|
36472
36473
|
import { spawn as spawn9 } from "node:child_process";
|
|
36473
36474
|
import { createHash as createHash9, randomBytes as randomBytes12 } from "node:crypto";
|
|
36474
|
-
import { rm as rm13 } from "node:fs/promises";
|
|
36475
|
+
import { rm as rm13, stat as stat16 } from "node:fs/promises";
|
|
36475
36476
|
import { hostname as osHostname2 } from "node:os";
|
|
36476
36477
|
import { join as join33 } from "node:path";
|
|
36477
36478
|
import { parseArgs } from "node:util";
|
|
@@ -36944,6 +36945,11 @@ var Output = class {
|
|
|
36944
36945
|
if (this.activities.size) this.progress(null);
|
|
36945
36946
|
this.stderr.write(`${this.render(text6, "err")}
|
|
36946
36947
|
`);
|
|
36948
|
+
}
|
|
36949
|
+
/** The keyboard list (tui.ts): CLI-owned cursor control plus rendered lines in one write, so a redraw never flickers. */
|
|
36950
|
+
screen(control, lines) {
|
|
36951
|
+
this.stdout.write(control + lines.map((line) => `${this.render(line, "out")}
|
|
36952
|
+
`).join(""));
|
|
36947
36953
|
}
|
|
36948
36954
|
/** CLI-owned OSC-8 link. The label/URI are neutralized; JSON, pipes and dumb terminals get a plain URL. */
|
|
36949
36955
|
link(label, uri, stream = "out") {
|
|
@@ -37270,20 +37276,32 @@ var EN = {
|
|
|
37270
37276
|
"menu.setupServer": "Server: {server}",
|
|
37271
37277
|
"menu.resume": "Continue {key}",
|
|
37272
37278
|
"menu.ticketDefault": "Ticket key (Enter = {key}):",
|
|
37273
|
-
"menu.fix": "Setup needs attention: {command}
|
|
37274
|
-
"menu.
|
|
37279
|
+
"menu.fix": "Setup needs attention: {command}. Open status and repair.",
|
|
37280
|
+
"menu.recommended": "Recommended",
|
|
37281
|
+
"menu.quit": "Quit",
|
|
37282
|
+
"menu.loading": "Loading …",
|
|
37283
|
+
"menu.yes": "Yes",
|
|
37284
|
+
"menu.no": "No",
|
|
37285
|
+
"menu.yesNo": "(y/N)",
|
|
37286
|
+
"menu.setupComputer": "Set up this computer",
|
|
37287
|
+
"menu.switchCheckout": "Switch checkout",
|
|
37288
|
+
"menu.checkoutTitle": "Which checkout do you want to work in?",
|
|
37289
|
+
"menu.key.move": "↑↓ move",
|
|
37290
|
+
"menu.key.open": "Enter open",
|
|
37291
|
+
"menu.key.confirm": "Enter confirm",
|
|
37292
|
+
"menu.key.back": "Esc back",
|
|
37293
|
+
"menu.key.cancel": "Esc cancel",
|
|
37294
|
+
"menu.key.quit": "q quit",
|
|
37275
37295
|
"menu.connect": "Connect this computer",
|
|
37276
|
-
"menu.bind": "Choose a checkout or set up this computer",
|
|
37277
37296
|
"menu.pick": "My next ticket",
|
|
37278
37297
|
"menu.continue": "Continue a ticket",
|
|
37279
37298
|
"menu.doctor": "Status and repair",
|
|
37280
37299
|
"menu.connections": "Connect ChatGPT / Claude · Settings › Connections",
|
|
37281
37300
|
"menu.help": "All commands",
|
|
37282
|
-
"menu.choose": "Number (Enter
|
|
37283
|
-
"menu.checkout": "Checkout number (0 = setup, Enter cancels):",
|
|
37301
|
+
"menu.choose": "Number (Enter quits):",
|
|
37284
37302
|
"menu.code": "Paste fleek setup <code> from Settings › Connections (Enter cancels):",
|
|
37285
37303
|
"menu.ticket": "Ticket key (Enter cancels):",
|
|
37286
|
-
"menu.repair": "Run {command} to review repair offers?
|
|
37304
|
+
"menu.repair": "Run {command} to review repair offers?",
|
|
37287
37305
|
"read.more": "More details: add --json.",
|
|
37288
37306
|
"read.empty": "No entries.",
|
|
37289
37307
|
"read.items": "Entries",
|
|
@@ -37484,6 +37502,7 @@ var EN = {
|
|
|
37484
37502
|
"errors.setupInstall": "The pinned CLI could not be installed permanently.",
|
|
37485
37503
|
"init.agentMissing": "Claude Code was not found. Manual mode is available.",
|
|
37486
37504
|
"init.agentUnknown": "Claude Code {version} is not yet verified for the analysis.",
|
|
37505
|
+
"init.agentOutdated": "Claude Code {version} is older than {minimum} and likely fails the analysis. Run claude update first.",
|
|
37487
37506
|
"init.confirmUnknownAgent": "Start it anyway with the same safety settings? (y/N)",
|
|
37488
37507
|
"init.agentBoundary": "Claude receives the prepared files with MCP, hooks and customizations disabled. Your provider sign-in remains available; this does not isolate the whole computer.",
|
|
37489
37508
|
"init.confirmAgent": "Start the read-only analysis now? (y/N)",
|
|
@@ -37491,7 +37510,14 @@ var EN = {
|
|
|
37491
37510
|
"errors.initAgentTimeout": "The analysis timed out; the agent was stopped.",
|
|
37492
37511
|
"errors.initAgentOutput": "The agent output exceeds the allowed size; nothing sent.",
|
|
37493
37512
|
"errors.initAgentStart": "Could not start Claude Code directly. Use --agent manual --verbose.",
|
|
37494
|
-
"errors.initAgentFailed": "Claude exited with code {code}
|
|
37513
|
+
"errors.initAgentFailed": "Claude exited with code {code} for an unknown reason; its output is not shown here. Rerun with --agent manual --verbose: Claude's own message is then in agent-output.json.tmp in the output directory.",
|
|
37514
|
+
"errors.initAgentFailed.next": "fleek init --agent manual --verbose",
|
|
37515
|
+
"errors.initAgentSignIn": "Claude is not signed in or its sign-in is no longer valid (code {code}). Sign in again, then rerun fleek init.",
|
|
37516
|
+
"errors.initAgentSignIn.next": "claude auth login",
|
|
37517
|
+
"errors.initAgentVersion": "Claude Code does not support the analysis start (code {code}); it is probably outdated. Update it, then rerun fleek init.",
|
|
37518
|
+
"errors.initAgentVersion.next": "claude update",
|
|
37519
|
+
"errors.initAgentRateLimit": "Claude reports a rate limit or overload (code {code}). Wait a moment, then rerun fleek init.",
|
|
37520
|
+
"errors.initAgentNetwork": "Claude could not reach its service (code {code}). Check the network connection, then rerun fleek init.",
|
|
37495
37521
|
"errors.initManualFallback": "Automatic analysis was not started. Continue with --agent manual --verbose.",
|
|
37496
37522
|
"login.serviceVisit": "Open {url} on your own computer and enter code {code}",
|
|
37497
37523
|
"login.serviceSetupConfirm": 'Confirm in the Fleek window where you generated the command ("Server asks to sign in"). Code: {code}',
|
|
@@ -37652,6 +37678,7 @@ var EN = {
|
|
|
37652
37678
|
"orca.rateWait": "Rate limit: waiting {seconds} s, then continuing at the same page.",
|
|
37653
37679
|
"orca.partial": "Partial list after {pages} pages. Narrow it with --project or --mine.",
|
|
37654
37680
|
"orca.listCount": "{count} open tickets · mine first, priority, recently updated",
|
|
37681
|
+
"orca.pickTitle": "{count} tickets · mine first, priority, recently updated",
|
|
37655
37682
|
"orca.pickPage": "Tickets {first}–{last} of {count} · mine first, priority, recently updated",
|
|
37656
37683
|
"orca.pickPages": "n: next page · p: previous page · enter any ticket number",
|
|
37657
37684
|
"errors.proxyProfileAmbiguous": "Several sign-ins are bound to this checkout. Pin one with --profile <key> or FLEEK_PROFILE.",
|
|
@@ -37922,7 +37949,7 @@ var EN = {
|
|
|
37922
37949
|
"init.detected": "Detected: {sources}",
|
|
37923
37950
|
"init.detectedNone": "no verified design sources",
|
|
37924
37951
|
"init.manualCommand": "In a separate terminal, with approved current Claude Code (keep every isolation flag):",
|
|
37925
|
-
"init.manualCommandHint": "Copy it whole, with the outer parentheses. command claude bypasses shell aliases and functions; keep every isolation flag.",
|
|
37952
|
+
"init.manualCommandHint": "Copy it whole, with the outer parentheses. command claude bypasses shell aliases and functions; keep every isolation flag. If Claude fails, its message is in agent-output.json.tmp in the output directory.",
|
|
37926
37953
|
"init.manualPrompt": "Read FLEEK-INIT.md and fleek-input.json. Read only the staged files. Return only the agent-output.json JSON object on stdout, without Markdown; the launcher saves it. Do not write files, run commands, use MCP or access the network.",
|
|
37927
37954
|
"init.manualBoundary": "You start the agent yourself: the file selection is only a recommendation, the agent may read more on your machine.",
|
|
37928
37955
|
"init.outputTimeout": "{app}: no output file in time.",
|
|
@@ -38037,20 +38064,32 @@ var DE = {
|
|
|
38037
38064
|
"menu.setupServer": "Server: {server}",
|
|
38038
38065
|
"menu.resume": "{key} weiterarbeiten",
|
|
38039
38066
|
"menu.ticketDefault": "Ticket-Schlüssel (Enter = {key}):",
|
|
38040
|
-
"menu.fix": "Einrichtung prüfen: {command}
|
|
38041
|
-
"menu.
|
|
38067
|
+
"menu.fix": "Einrichtung prüfen: {command}. Öffne Status und Reparatur.",
|
|
38068
|
+
"menu.recommended": "Empfohlen",
|
|
38069
|
+
"menu.quit": "Beenden",
|
|
38070
|
+
"menu.loading": "Lädt …",
|
|
38071
|
+
"menu.yes": "Ja",
|
|
38072
|
+
"menu.no": "Nein",
|
|
38073
|
+
"menu.yesNo": "(j/N)",
|
|
38074
|
+
"menu.setupComputer": "Rechner einrichten",
|
|
38075
|
+
"menu.switchCheckout": "Checkout wechseln",
|
|
38076
|
+
"menu.checkoutTitle": "In welchem Checkout möchtest du arbeiten?",
|
|
38077
|
+
"menu.key.move": "↑↓ wählen",
|
|
38078
|
+
"menu.key.open": "Enter öffnen",
|
|
38079
|
+
"menu.key.confirm": "Enter bestätigen",
|
|
38080
|
+
"menu.key.back": "Esc zurück",
|
|
38081
|
+
"menu.key.cancel": "Esc abbrechen",
|
|
38082
|
+
"menu.key.quit": "q beenden",
|
|
38042
38083
|
"menu.connect": "Rechner verbinden",
|
|
38043
|
-
"menu.bind": "Checkout wählen oder Rechner einrichten",
|
|
38044
38084
|
"menu.pick": "Mein nächstes Ticket",
|
|
38045
38085
|
"menu.continue": "Ticket fortsetzen",
|
|
38046
38086
|
"menu.doctor": "Status und Reparatur",
|
|
38047
38087
|
"menu.connections": "ChatGPT / Claude verbinden · Einstellungen › Verbindungen",
|
|
38048
38088
|
"menu.help": "Alle Befehle",
|
|
38049
|
-
"menu.choose": "Nummer (Enter
|
|
38050
|
-
"menu.checkout": "Checkout-Nummer (0 = Einrichtung, Enter bricht ab):",
|
|
38089
|
+
"menu.choose": "Nummer (Enter beendet):",
|
|
38051
38090
|
"menu.code": "fleek setup <code> aus Einstellungen › Verbindungen einfügen (Enter bricht ab):",
|
|
38052
38091
|
"menu.ticket": "Ticket-Schlüssel (Enter bricht ab):",
|
|
38053
|
-
"menu.repair": "Mit {command} Reparaturangebote prüfen?
|
|
38092
|
+
"menu.repair": "Mit {command} Reparaturangebote prüfen?",
|
|
38054
38093
|
"read.more": "Weitere Details: --json ergänzen.",
|
|
38055
38094
|
"read.empty": "Keine Einträge.",
|
|
38056
38095
|
"read.items": "Einträge",
|
|
@@ -38251,6 +38290,7 @@ var DE = {
|
|
|
38251
38290
|
"errors.setupInstall": "Die festgelegte CLI-Version konnte nicht dauerhaft installiert werden.",
|
|
38252
38291
|
"init.agentMissing": "Claude Code wurde nicht gefunden. Der manuelle Modus ist verfügbar.",
|
|
38253
38292
|
"init.agentUnknown": "Claude Code {version} ist für die Analyse noch nicht geprüft.",
|
|
38293
|
+
"init.agentOutdated": "Claude Code {version} ist älter als {minimum} und scheitert wahrscheinlich an der Analyse. Führe zuerst claude update aus.",
|
|
38254
38294
|
"init.confirmUnknownAgent": "Trotzdem mit denselben Schutzeinstellungen starten? (j/N)",
|
|
38255
38295
|
"init.agentBoundary": "Claude erhält die vorbereiteten Dateien; MCP, Hooks und Anpassungen sind deaktiviert. Deine Anbieteranmeldung bleibt verfügbar; der Rechner wird dabei nicht vollständig isoliert.",
|
|
38256
38296
|
"init.confirmAgent": "Die Analyse jetzt nur lesend starten? (j/N)",
|
|
@@ -38258,7 +38298,14 @@ var DE = {
|
|
|
38258
38298
|
"errors.initAgentTimeout": "Die Analyse hat die Frist überschritten; der Agent wurde gestoppt.",
|
|
38259
38299
|
"errors.initAgentOutput": "Die Agentenausgabe überschreitet die erlaubte Größe; nichts gesendet.",
|
|
38260
38300
|
"errors.initAgentStart": "Claude Code konnte nicht direkt gestartet werden. Nutze --agent manual --verbose.",
|
|
38261
|
-
"errors.initAgentFailed": "Claude wurde mit Code {code} beendet
|
|
38301
|
+
"errors.initAgentFailed": "Claude wurde aus unbekanntem Grund mit Code {code} beendet; seine Ausgabe wird hier nicht angezeigt. Starte erneut mit --agent manual --verbose: Claudes eigene Meldung steht dann in agent-output.json.tmp im Ausgabeverzeichnis.",
|
|
38302
|
+
"errors.initAgentFailed.next": "fleek init --agent manual --verbose",
|
|
38303
|
+
"errors.initAgentSignIn": "Claude ist nicht angemeldet oder die Anmeldung ist nicht mehr gültig (Code {code}). Melde dich neu an und starte fleek init dann erneut.",
|
|
38304
|
+
"errors.initAgentSignIn.next": "claude auth login",
|
|
38305
|
+
"errors.initAgentVersion": "Claude Code unterstützt den Analysestart nicht (Code {code}); vermutlich ist es veraltet. Aktualisiere es und starte fleek init dann erneut.",
|
|
38306
|
+
"errors.initAgentVersion.next": "claude update",
|
|
38307
|
+
"errors.initAgentRateLimit": "Claude meldet ein Nutzungslimit oder eine Überlastung (Code {code}). Warte kurz und starte fleek init dann erneut.",
|
|
38308
|
+
"errors.initAgentNetwork": "Claude konnte seinen Dienst nicht erreichen (Code {code}). Prüfe die Netzwerkverbindung und starte fleek init dann erneut.",
|
|
38262
38309
|
"errors.initManualFallback": "Die automatische Analyse wurde nicht gestartet. Fahre mit --agent manual --verbose fort.",
|
|
38263
38310
|
"login.serviceVisit": "Öffne {url} am eigenen Rechner und gib den Code {code} ein.",
|
|
38264
38311
|
"login.serviceSetupConfirm": "Bestätige im Fleek-Fenster, in dem du den Befehl erzeugt hast (‚Server fragt Anmeldung an‘). Code: {code}",
|
|
@@ -38419,6 +38466,7 @@ var DE = {
|
|
|
38419
38466
|
"orca.rateWait": "Anfragelimit: {seconds} s warten, dann auf derselben Seite fortsetzen.",
|
|
38420
38467
|
"orca.partial": "Teilliste nach {pages} Seiten. Mit --project oder --mine eingrenzen.",
|
|
38421
38468
|
"orca.listCount": "{count} offene Tickets · eigene zuerst, Priorität, zuletzt aktualisiert",
|
|
38469
|
+
"orca.pickTitle": "{count} Tickets · eigene zuerst, Priorität, zuletzt aktualisiert",
|
|
38422
38470
|
"orca.pickPage": "Tickets {first}–{last} von {count} · eigene zuerst, Priorität, zuletzt aktualisiert",
|
|
38423
38471
|
"orca.pickPages": "n: nächste Seite · p: vorherige Seite · beliebige Ticket-Nummer eingeben",
|
|
38424
38472
|
"errors.proxyProfileAmbiguous": "Mehrere Anmeldungen sind an dieses Repo gebunden. Leg eine fest mit --profile <schlüssel> oder FLEEK_PROFILE.",
|
|
@@ -38689,7 +38737,7 @@ var DE = {
|
|
|
38689
38737
|
"init.detected": "Erkannt: {sources}",
|
|
38690
38738
|
"init.detectedNone": "keine belegten Design-Quellen",
|
|
38691
38739
|
"init.manualCommand": "In einem separaten Terminal mit freigegebenem aktuellem Claude Code (alle Isolationsflags beibehalten):",
|
|
38692
|
-
"init.manualCommandHint": "Ganz kopieren, mit den äußeren Klammern. command claude umgeht Shell-Aliase und Funktionen; behalte alle Isolationsflags bei.",
|
|
38740
|
+
"init.manualCommandHint": "Ganz kopieren, mit den äußeren Klammern. command claude umgeht Shell-Aliase und Funktionen; behalte alle Isolationsflags bei. Scheitert Claude, steht seine Meldung in agent-output.json.tmp im Ausgabeverzeichnis.",
|
|
38693
38741
|
"init.manualPrompt": "Lies FLEEK-INIT.md und fleek-input.json. Lies nur die bereitgestellten Dateien. Gib nur das JSON-Objekt für agent-output.json auf stdout aus, ohne Markdown; der Startbefehl speichert es. Keine Dateien schreiben, keine Befehle, kein MCP und kein Netzzugriff.",
|
|
38694
38742
|
"init.manualBoundary": "Du startest den Agenten selbst: Die Dateiauswahl ist nur eine Empfehlung, der Agent kann auf deinem Rechner mehr lesen.",
|
|
38695
38743
|
"init.outputTimeout": "{app}: keine Ausgabedatei innerhalb der Frist.",
|
|
@@ -38791,8 +38839,8 @@ async function processStart(pid) {
|
|
|
38791
38839
|
if (process.platform === "win32") return null;
|
|
38792
38840
|
if (process.platform === "linux") {
|
|
38793
38841
|
try {
|
|
38794
|
-
const
|
|
38795
|
-
const fields =
|
|
38842
|
+
const stat17 = await readFile2(`/proc/${pid}/stat`, "utf8");
|
|
38843
|
+
const fields = stat17.slice(stat17.lastIndexOf(")") + 2).split(" ");
|
|
38796
38844
|
const ticks = Number(fields[19]);
|
|
38797
38845
|
return Number.isSafeInteger(ticks) ? ticks : null;
|
|
38798
38846
|
} catch {
|
|
@@ -49700,7 +49748,7 @@ async function reloadProxyProfile(store, started) {
|
|
|
49700
49748
|
// src/orca.ts
|
|
49701
49749
|
import { execFile as nodeExecFile } from "node:child_process";
|
|
49702
49750
|
import { realpath as realpath4 } from "node:fs/promises";
|
|
49703
|
-
import { posix, win32 } from "node:path";
|
|
49751
|
+
import { posix as posix2, win32 as win322 } from "node:path";
|
|
49704
49752
|
import { setTimeout as sleep4 } from "node:timers/promises";
|
|
49705
49753
|
|
|
49706
49754
|
// src/tools.ts
|
|
@@ -49757,12 +49805,277 @@ var WIRE = {
|
|
|
49757
49805
|
reportServiceHost: "fleek_report_service_host"
|
|
49758
49806
|
};
|
|
49759
49807
|
|
|
49808
|
+
// src/header.ts
|
|
49809
|
+
import { win32, posix } from "node:path";
|
|
49810
|
+
|
|
49811
|
+
// src/uuid.ts
|
|
49812
|
+
var UUID2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
49813
|
+
function isUuid(value) {
|
|
49814
|
+
return UUID2.test(value);
|
|
49815
|
+
}
|
|
49816
|
+
function canonicalId(value) {
|
|
49817
|
+
if (!UUID2.test(value)) throw new Error("INVALID_UUID");
|
|
49818
|
+
return value.toLowerCase();
|
|
49819
|
+
}
|
|
49820
|
+
|
|
49821
|
+
// src/header.ts
|
|
49822
|
+
var LOGO2 = [" ▄██████▀", " ▄█████▀ ", " ██▀ "];
|
|
49823
|
+
var ASCII_LOGO = [" ######/", " #####/ ", " ##/ "];
|
|
49824
|
+
var BRAND = "\x1B[38;2;69;94;255m";
|
|
49825
|
+
function shouldShowHeader(positionals, options, terminal) {
|
|
49826
|
+
if (options.json || options.version || terminal.stream.isTTY !== true) return false;
|
|
49827
|
+
const active = (value) => value !== void 0 && value !== "" && value !== "0" && value !== "false";
|
|
49828
|
+
if (["CI", "CONTINUOUS_INTEGRATION", "GITHUB_ACTIONS", "BUILD_NUMBER", "TF_BUILD"].some((key) => active(terminal.env[key]))) return false;
|
|
49829
|
+
const [command, sub] = positionals;
|
|
49830
|
+
return !command || command === "help" || !!options.help || command === "setup" || command === "doctor" || command === "init" || command === "kit" && ["setup", "doctor", "pull"].includes(sub ?? "") || command === "service" && sub === "setup";
|
|
49831
|
+
}
|
|
49832
|
+
function cells(value) {
|
|
49833
|
+
let width = 0;
|
|
49834
|
+
for (const char of value) {
|
|
49835
|
+
const code = char.codePointAt(0);
|
|
49836
|
+
if (new RegExp("\\p{Mark}", "u").test(char)) continue;
|
|
49837
|
+
width += code >= 4352 && (code <= 4447 || code >= 11904 && code <= 42191 || code >= 44032 && code <= 55203 || code >= 63744 && code <= 64255 || code >= 65040 && code <= 65135 || code >= 65281 && code <= 65376 || code >= 65504 && code <= 65510 || code >= 127744) ? 2 : 1;
|
|
49838
|
+
}
|
|
49839
|
+
return width;
|
|
49840
|
+
}
|
|
49841
|
+
function fit(value, width, ascii) {
|
|
49842
|
+
if (cells(value) <= width) return value;
|
|
49843
|
+
const suffix = ascii ? "..." : "…";
|
|
49844
|
+
if (width <= suffix.length) return suffix.slice(0, Math.max(0, width));
|
|
49845
|
+
let out = "";
|
|
49846
|
+
for (const char of value) {
|
|
49847
|
+
if (cells(out + char) > width - suffix.length) break;
|
|
49848
|
+
out += char;
|
|
49849
|
+
}
|
|
49850
|
+
return out + suffix;
|
|
49851
|
+
}
|
|
49852
|
+
var safe = (value) => neutralizeLine(redact(value));
|
|
49853
|
+
function directory(context, windows, env) {
|
|
49854
|
+
const path = windows ? win32 : posix;
|
|
49855
|
+
const home = context.home ?? userHome(env, windows ? "win32" : process.platform);
|
|
49856
|
+
const relative3 = path.relative(home, context.cwd);
|
|
49857
|
+
const inside = relative3 === "" || relative3 !== ".." && !relative3.startsWith(`..${path.sep}`) && !path.isAbsolute(relative3);
|
|
49858
|
+
return safe(inside ? relative3 ? `~${path.sep}${relative3}` : "~" : context.cwd);
|
|
49859
|
+
}
|
|
49860
|
+
function displayPath(cwd, home, env) {
|
|
49861
|
+
return directory({ version: "", cwd, home }, process.platform === "win32", env);
|
|
49862
|
+
}
|
|
49863
|
+
function headerServer(value) {
|
|
49864
|
+
if (!value) return void 0;
|
|
49865
|
+
try {
|
|
49866
|
+
const url = new URL(value);
|
|
49867
|
+
return ["http:", "https:"].includes(url.protocol) ? url.host : void 0;
|
|
49868
|
+
} catch {
|
|
49869
|
+
return void 0;
|
|
49870
|
+
}
|
|
49871
|
+
}
|
|
49872
|
+
function renderHeader(context, terminal, t) {
|
|
49873
|
+
const windows = (terminal.platform ?? process.platform) === "win32";
|
|
49874
|
+
const ascii = windows || terminal.env.TERM === "dumb";
|
|
49875
|
+
const separator = ascii ? " - " : " · ";
|
|
49876
|
+
const requested = terminal.stream.columns ?? Number(terminal.env.COLUMNS);
|
|
49877
|
+
const columns = Number.isFinite(requested) && requested > 0 ? Math.floor(requested) : 80;
|
|
49878
|
+
const title = t("header.title", { version: safe(context.version) });
|
|
49879
|
+
const cwd = directory(context, windows, terminal.env);
|
|
49880
|
+
const parts = [context.workspace, context.project && !isUuid(context.project) ? context.project : void 0, headerServer(context.server), context.displayName].filter((value) => !!value);
|
|
49881
|
+
const details = parts.length ? parts.map(safe).join(separator) : t("header.noContext");
|
|
49882
|
+
if (columns < 60) return ["", fit([title, cwd].join(separator), columns, ascii)];
|
|
49883
|
+
const logo = ascii ? ASCII_LOGO : LOGO2;
|
|
49884
|
+
const width = Math.max(...logo.map(cells));
|
|
49885
|
+
const color = colorEnabled(terminal.env, terminal.stream);
|
|
49886
|
+
const available2 = columns - width - 6;
|
|
49887
|
+
const tagline = separator + t("header.tagline");
|
|
49888
|
+
const attribution = separator + t("header.attribution");
|
|
49889
|
+
const secondary = cells(title + tagline) <= available2 ? tagline + (cells(title + tagline + attribution) <= available2 ? attribution : "") : "";
|
|
49890
|
+
const text6 = [title, details, cwd];
|
|
49891
|
+
const rows = logo.map((row, index) => {
|
|
49892
|
+
const mark = row.padEnd(width);
|
|
49893
|
+
const label = fit(text6[index], available2, ascii);
|
|
49894
|
+
if (index === 0) {
|
|
49895
|
+
const heading = color ? `\x1B[1m${label}\x1B[22m` : label;
|
|
49896
|
+
const branding = color && secondary ? `\x1B[2m${secondary}\x1B[22m` : secondary;
|
|
49897
|
+
return `${color ? `${BRAND}${mark}\x1B[39m` : mark} ${heading}${branding}`;
|
|
49898
|
+
}
|
|
49899
|
+
const styled = color ? `\x1B[2m${label}\x1B[22m` : label;
|
|
49900
|
+
return `${color ? `${BRAND}${mark}\x1B[39m` : mark} ${styled}`;
|
|
49901
|
+
});
|
|
49902
|
+
const inner = Math.max(...rows.map((row) => cells(stripAnsi(row))));
|
|
49903
|
+
const edge = (value) => color ? `${BRAND}${value}\x1B[39m` : value;
|
|
49904
|
+
const vertical = ascii ? "|" : "│";
|
|
49905
|
+
return [
|
|
49906
|
+
"",
|
|
49907
|
+
edge(`${ascii ? "+" : "╭"}${(ascii ? "-" : "─").repeat(inner + 2)}${ascii ? "+" : "╮"}`),
|
|
49908
|
+
...rows.map((row) => `${edge(vertical)} ${row}${" ".repeat(inner - cells(stripAnsi(row)))} ${edge(vertical)}`),
|
|
49909
|
+
edge(`${ascii ? "+" : "╰"}${(ascii ? "-" : "─").repeat(inner + 2)}${ascii ? "+" : "╯"}`)
|
|
49910
|
+
];
|
|
49911
|
+
}
|
|
49912
|
+
function printHeader(out, context, terminal, t) {
|
|
49913
|
+
for (const line of renderHeader(context, terminal, t)) out.line(line);
|
|
49914
|
+
out.line();
|
|
49915
|
+
out.indentHumanOutput();
|
|
49916
|
+
}
|
|
49917
|
+
|
|
49918
|
+
// src/tui.ts
|
|
49919
|
+
var yesNoList = (question, t) => ({
|
|
49920
|
+
title: [question],
|
|
49921
|
+
items: [{ id: "no", label: t("menu.no") }, { id: "yes", label: t("menu.yes") }],
|
|
49922
|
+
initial: "no",
|
|
49923
|
+
back: true,
|
|
49924
|
+
confirm: true,
|
|
49925
|
+
echo: (item2) => `${question} ${item2.label}`
|
|
49926
|
+
});
|
|
49927
|
+
var isYes = (result) => result.kind === "select" && result.id === "yes";
|
|
49928
|
+
function isKeyInput(stream) {
|
|
49929
|
+
const input = stream;
|
|
49930
|
+
return !!input && input.isTTY === true && typeof input.setRawMode === "function";
|
|
49931
|
+
}
|
|
49932
|
+
var SEQUENCE = /\u001b\[[0-9;]*[A-Za-z~]|\u001bO[A-Za-z]|[\s\S]/g;
|
|
49933
|
+
var NAMED = {
|
|
49934
|
+
"\x1B[A": "up",
|
|
49935
|
+
"\x1BOA": "up",
|
|
49936
|
+
k: "up",
|
|
49937
|
+
"\x1B[B": "down",
|
|
49938
|
+
"\x1BOB": "down",
|
|
49939
|
+
j: "down",
|
|
49940
|
+
"\x1B[H": "home",
|
|
49941
|
+
"\x1BOH": "home",
|
|
49942
|
+
"\x1B[1~": "home",
|
|
49943
|
+
"\x1B[F": "end",
|
|
49944
|
+
"\x1BOF": "end",
|
|
49945
|
+
"\x1B[4~": "end",
|
|
49946
|
+
"\x1B[5~": "pageUp",
|
|
49947
|
+
"\x1B[6~": "pageDown",
|
|
49948
|
+
"\r": "enter",
|
|
49949
|
+
"\n": "enter",
|
|
49950
|
+
"\x1B[C": "enter",
|
|
49951
|
+
"\x1BOC": "enter",
|
|
49952
|
+
"\x1B": "back",
|
|
49953
|
+
"\x1B[D": "back",
|
|
49954
|
+
"\x1BOD": "back",
|
|
49955
|
+
q: "quit",
|
|
49956
|
+
"": "abort",
|
|
49957
|
+
"": "abort"
|
|
49958
|
+
};
|
|
49959
|
+
function parseKeys(chunk) {
|
|
49960
|
+
return (chunk.match(SEQUENCE) ?? []).flatMap((part) => {
|
|
49961
|
+
const named = NAMED[part];
|
|
49962
|
+
if (named) return [named];
|
|
49963
|
+
return /^[1-9]$/.test(part) ? [`digit${Number(part)}`] : [];
|
|
49964
|
+
});
|
|
49965
|
+
}
|
|
49966
|
+
function wrap(text6, width) {
|
|
49967
|
+
const lines = [];
|
|
49968
|
+
let line = "";
|
|
49969
|
+
for (const word of text6.split(" ")) {
|
|
49970
|
+
if (line && cells(`${line} ${word}`) > width) {
|
|
49971
|
+
lines.push(line);
|
|
49972
|
+
line = "";
|
|
49973
|
+
}
|
|
49974
|
+
line = line ? `${line} ${word}` : word;
|
|
49975
|
+
}
|
|
49976
|
+
return [...lines, line].map((entry) => fit(entry, width, false));
|
|
49977
|
+
}
|
|
49978
|
+
function selectList(terminal, options) {
|
|
49979
|
+
const { stdin, stdout, out, t } = terminal;
|
|
49980
|
+
const s = out.style, items = options.items;
|
|
49981
|
+
const pointer = s.unicode ? "›" : ">";
|
|
49982
|
+
let cursor = Math.max(0, items.findIndex((item2) => item2.id === options.initial));
|
|
49983
|
+
let top = 0, drawn = 0;
|
|
49984
|
+
const footer = () => [
|
|
49985
|
+
t("menu.key.move"),
|
|
49986
|
+
t(options.confirm ? "menu.key.confirm" : "menu.key.open"),
|
|
49987
|
+
...options.back ? [t(options.confirm ? "menu.key.cancel" : "menu.key.back")] : [],
|
|
49988
|
+
...options.quit ? [t("menu.key.quit")] : []
|
|
49989
|
+
].join(` ${s.glyph.bullet} `);
|
|
49990
|
+
const view = () => {
|
|
49991
|
+
const width = Math.max(20, (stdout.columns ?? 80) - 3);
|
|
49992
|
+
const title = [
|
|
49993
|
+
...options.context ? [s.dim(fit(neutralizeLine(options.context), width, !s.unicode))] : [],
|
|
49994
|
+
...(options.title ?? []).flatMap((line) => wrap(neutralizeLine(line), width)).map((line) => s.bold(line))
|
|
49995
|
+
];
|
|
49996
|
+
const room = Math.max(3, (stdout.rows ?? 24) - title.length - 5);
|
|
49997
|
+
const size = Math.min(items.length, room);
|
|
49998
|
+
if (cursor < top) top = cursor;
|
|
49999
|
+
if (cursor >= top + size) top = cursor - size + 1;
|
|
50000
|
+
top = Math.min(top, items.length - size);
|
|
50001
|
+
const shown3 = items.slice(top, top + size).map((item2) => ({ item: item2, label: neutralizeLine(item2.label), hint: item2.hint ? neutralizeLine(item2.hint) : "" }));
|
|
50002
|
+
const column = Math.max(...shown3.map(({ label, hint }) => hint ? cells(label) : 0));
|
|
50003
|
+
const rows = shown3.map(({ item: item2, label, hint }) => {
|
|
50004
|
+
const room2 = hint ? width - 2 - cells(hint) - 2 : width - 2;
|
|
50005
|
+
const text6 = fit(label, room2, !s.unicode);
|
|
50006
|
+
const pad = hint ? " ".repeat(Math.max(2, column - cells(text6) + 2)) : "";
|
|
50007
|
+
const chosen = items[cursor] === item2;
|
|
50008
|
+
return `${chosen ? s.cmd(`${pointer} `) : " "}${chosen ? s.bold(s.cmd(text6)) : text6}${pad}${hint ? s.dim(hint) : ""}`;
|
|
50009
|
+
});
|
|
50010
|
+
const position = items.length > size ? `${cursor + 1}/${items.length} ${s.glyph.bullet} ` : "";
|
|
50011
|
+
return [...title, ...title.length ? [""] : [], ...rows, "", s.dim(`${position}${footer()}`)];
|
|
50012
|
+
};
|
|
50013
|
+
const draw = () => {
|
|
50014
|
+
const lines = view();
|
|
50015
|
+
out.screen(`${drawn ? `\x1B[${drawn}A` : ""}\r\x1B[J`, lines);
|
|
50016
|
+
drawn = lines.length;
|
|
50017
|
+
};
|
|
50018
|
+
return new Promise((resolve9) => {
|
|
50019
|
+
const showCursor = () => out.screen("\x1B[?25h", []);
|
|
50020
|
+
const finish2 = (result) => {
|
|
50021
|
+
stdin.off("data", onData);
|
|
50022
|
+
stdin.off("end", onEnd);
|
|
50023
|
+
stdout.off?.("resize", draw);
|
|
50024
|
+
process.off("exit", showCursor);
|
|
50025
|
+
stdin.setRawMode(false);
|
|
50026
|
+
stdin.pause();
|
|
50027
|
+
out.screen(`\x1B[${drawn}A\r\x1B[J\x1B[?25h`, []);
|
|
50028
|
+
if (result.kind === "select") {
|
|
50029
|
+
const item2 = items[cursor];
|
|
50030
|
+
out.line(s.dim(`${pointer} ${neutralizeLine(options.echo ? options.echo(item2) : item2.label)}`));
|
|
50031
|
+
}
|
|
50032
|
+
resolve9(result);
|
|
50033
|
+
};
|
|
50034
|
+
const onEnd = () => finish2({ kind: "abort" });
|
|
50035
|
+
const onData = (chunk) => {
|
|
50036
|
+
for (const key of parseKeys(String(chunk))) {
|
|
50037
|
+
if (key === "abort") return finish2({ kind: "abort" });
|
|
50038
|
+
if (key === "quit" && options.quit) return finish2({ kind: "quit" });
|
|
50039
|
+
if (key === "quit" && options.back) return finish2({ kind: "back" });
|
|
50040
|
+
if (key === "back" && options.back) return finish2({ kind: "back" });
|
|
50041
|
+
if (key === "enter") return finish2({ kind: "select", id: items[cursor].id });
|
|
50042
|
+
if (key === "up") cursor = (cursor - 1 + items.length) % items.length;
|
|
50043
|
+
else if (key === "down") cursor = (cursor + 1) % items.length;
|
|
50044
|
+
else if (key === "home") cursor = 0;
|
|
50045
|
+
else if (key === "end") cursor = items.length - 1;
|
|
50046
|
+
else if (key === "pageUp") cursor = Math.max(0, cursor - 10);
|
|
50047
|
+
else if (key === "pageDown") cursor = Math.min(items.length - 1, cursor + 10);
|
|
50048
|
+
else if (key.startsWith("digit") && !options.confirm) {
|
|
50049
|
+
const index = Number(key.slice(5)) - 1;
|
|
50050
|
+
if (items[index]) {
|
|
50051
|
+
cursor = index;
|
|
50052
|
+
return finish2({ kind: "select", id: items[index].id });
|
|
50053
|
+
}
|
|
50054
|
+
}
|
|
50055
|
+
}
|
|
50056
|
+
draw();
|
|
50057
|
+
};
|
|
50058
|
+
process.once("exit", showCursor);
|
|
50059
|
+
stdin.setRawMode(true);
|
|
50060
|
+
stdin.resume();
|
|
50061
|
+
stdin.on("data", onData);
|
|
50062
|
+
stdin.once("end", onEnd);
|
|
50063
|
+
stdout.on?.("resize", draw);
|
|
50064
|
+
out.screen("\x1B[?25l", []);
|
|
50065
|
+
draw();
|
|
50066
|
+
});
|
|
50067
|
+
}
|
|
50068
|
+
|
|
49760
50069
|
// src/orca.ts
|
|
49761
50070
|
var ORCA_LIMITS = { items: 200, projects: 200, title: 1e3, status: 120, id: 200 };
|
|
49762
50071
|
var KEY = /^[A-Z0-9]{2,10}-[1-9][0-9]*$/;
|
|
49763
|
-
var
|
|
50072
|
+
var UUID3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
49764
50073
|
var CLOSED = /* @__PURE__ */ new Set(["completed", "cancelled", "canceled"]);
|
|
49765
|
-
var terminalConfirm = (deps) => async (question) =>
|
|
50074
|
+
var terminalConfirm = (deps) => async (question) => {
|
|
50075
|
+
if (!deps.isTTY || !deps.ask) return null;
|
|
50076
|
+
if (deps.select) return isYes(await deps.select(yesNoList(question, deps.t)));
|
|
50077
|
+
return /^(y|yes|j|ja)$/i.test((await deps.ask(`${question} (y/N)`)).trim());
|
|
50078
|
+
};
|
|
49766
50079
|
var notBound = () => new CliError("errors.orcaNotBound", EXIT.failed, {}, "NOT_BOUND");
|
|
49767
50080
|
var usage = () => new CliError("errors.usage", EXIT.usage, {}, "USAGE");
|
|
49768
50081
|
var bounded = (value, max) => String(value ?? "").slice(0, max);
|
|
@@ -49829,7 +50142,7 @@ async function readTool(client, tool, args, read2) {
|
|
|
49829
50142
|
}
|
|
49830
50143
|
async function claimableIds(client, teamId, read2) {
|
|
49831
50144
|
const candidates = await pages(client, WIRE.findWork, { ...teamId ? { teamId } : {} }, void 0, read2);
|
|
49832
|
-
return new Set(candidates.filter((row) => Array.isArray(row.claims) && !row.claims.some((claim) => object3(claim) && claim.purpose === "work") && (!object3(row.eligibility) || row.eligibility.allowAgents === true && !row.eligibility.blockedBy) && (!object3(row.request) || row.request.canTake !== false)).map((row) => String(row.issueId ?? "").toLowerCase()).filter((id) =>
|
|
50145
|
+
return new Set(candidates.filter((row) => Array.isArray(row.claims) && !row.claims.some((claim) => object3(claim) && claim.purpose === "work") && (!object3(row.eligibility) || row.eligibility.allowAgents === true && !row.eligibility.blockedBy) && (!object3(row.request) || row.request.canTake !== false)).map((row) => String(row.issueId ?? "").toLowerCase()).filter((id) => UUID3.test(id)));
|
|
49833
50146
|
}
|
|
49834
50147
|
async function pages(client, tool, args, max = Number.POSITIVE_INFINITY, read2) {
|
|
49835
50148
|
await available(client, tool);
|
|
@@ -49870,7 +50183,7 @@ function sortIssues(issues, mine) {
|
|
|
49870
50183
|
return [...issues].sort((a, b) => Number(mine.has(b.id)) - Number(mine.has(a.id)) || priority(a) - priority(b) || updated(b) - updated(a) || String(a.identifier ?? "").localeCompare(String(b.identifier ?? ""), "en", { numeric: true }));
|
|
49871
50184
|
}
|
|
49872
50185
|
async function teams(client, read2) {
|
|
49873
|
-
return (await pages(client, "fleek_list_teams", {}, ORCA_LIMITS.projects, read2)).filter((team) => typeof team.id === "string" &&
|
|
50186
|
+
return (await pages(client, "fleek_list_teams", {}, ORCA_LIMITS.projects, read2)).filter((team) => typeof team.id === "string" && UUID3.test(team.id)).map((team) => ({ id: team.id.toLowerCase(), key: bounded(team.key, 32), name: bounded(team.name, 512) }));
|
|
49874
50187
|
}
|
|
49875
50188
|
async function statesOf(client, teamIds, read2) {
|
|
49876
50189
|
const states = /* @__PURE__ */ new Map();
|
|
@@ -49882,9 +50195,9 @@ async function statesOf(client, teamIds, read2) {
|
|
|
49882
50195
|
return states;
|
|
49883
50196
|
}
|
|
49884
50197
|
function item(profile, issue, teamsById, states) {
|
|
49885
|
-
const id = typeof issue.id === "string" &&
|
|
50198
|
+
const id = typeof issue.id === "string" && UUID3.test(issue.id) ? issue.id.toLowerCase() : null;
|
|
49886
50199
|
const key = typeof issue.identifier === "string" && KEY.test(issue.identifier) ? issue.identifier : null;
|
|
49887
|
-
const teamId = typeof issue.teamId === "string" &&
|
|
50200
|
+
const teamId = typeof issue.teamId === "string" && UUID3.test(issue.teamId) ? issue.teamId.toLowerCase() : null;
|
|
49888
50201
|
if (!id || !key || !teamId) return null;
|
|
49889
50202
|
const status = typeof issue.stateId === "string" ? states.get(issue.stateId.toLowerCase())?.name ?? "" : "";
|
|
49890
50203
|
return { id, key, title: bounded(issue.title, ORCA_LIMITS.title), status, url: ticketUrl(profile, teamsById.get(teamId)?.key ?? null, key), projectId: teamId };
|
|
@@ -49892,14 +50205,14 @@ function item(profile, issue, teamsById, states) {
|
|
|
49892
50205
|
function projectOf(values, found, list2) {
|
|
49893
50206
|
if (values.project === void 0) return found.projectId;
|
|
49894
50207
|
const value = values.project.trim();
|
|
49895
|
-
const match =
|
|
50208
|
+
const match = UUID3.test(value) ? list2.find((team) => team.id === value.toLowerCase()) : list2.find((team) => team.key.toUpperCase() === value.toUpperCase());
|
|
49896
50209
|
if (!match) throw new CliError("errors.orcaProjectUnknown", EXIT.usage, {}, "NOT_FOUND");
|
|
49897
50210
|
return match.id;
|
|
49898
50211
|
}
|
|
49899
50212
|
async function myUserId(client, read2) {
|
|
49900
50213
|
const who = (await readTool(client, WIRE.whoami, {}, read2)).structured;
|
|
49901
50214
|
const id = who.principal?.userId;
|
|
49902
|
-
if (typeof id !== "string" || !
|
|
50215
|
+
if (typeof id !== "string" || !UUID3.test(id)) throw new CliError("errors.metadata", EXIT.failed, { reason: "context" }, "METADATA_INVALID");
|
|
49903
50216
|
return id.toLowerCase();
|
|
49904
50217
|
}
|
|
49905
50218
|
async function orcaContext(deps, values = {}) {
|
|
@@ -49997,7 +50310,7 @@ var defaultExec = (program, args, options) => new Promise((resolve9) => nodeExec
|
|
|
49997
50310
|
(error, stdout, stderr) => resolve9({ code: error ? typeof error.code === "number" ? error.code : 1 : 0, stdout: String(stdout), stderr: String(stderr) })
|
|
49998
50311
|
));
|
|
49999
50312
|
async function orcaProgram(deps, runtime = { platform: process.platform }) {
|
|
50000
|
-
const paths = runtime.platform === "win32" ?
|
|
50313
|
+
const paths = runtime.platform === "win32" ? win322 : posix2;
|
|
50001
50314
|
const custom = deps.env.ORCA_CLI_COMMAND || void 0;
|
|
50002
50315
|
const found = custom ?? (runtime.platform === "linux" ? await deps.which("orca-ide") : null) ?? await deps.which("orca");
|
|
50003
50316
|
if (!found || !paths.isAbsolute(found) || paths.resolve(found) === "/usr/bin/orca" || await (runtime.realpath ?? realpath4)(found).catch(() => found) === "/usr/bin/orca") {
|
|
@@ -50037,6 +50350,11 @@ async function orcaPick(deps, values, start2) {
|
|
|
50037
50350
|
deps.out.line(deps.out.style.note(deps.t("orca.none")));
|
|
50038
50351
|
return EXIT.ok;
|
|
50039
50352
|
}
|
|
50353
|
+
if (deps.select) {
|
|
50354
|
+
const rows = deps.out.style.columns(items.map((entry) => [entry.key, mineIds.has(entry.id) ? deps.t("orca.mine") : "", neutralizeLine(entry.status), neutralizeLine(entry.title).slice(0, 100)]), "");
|
|
50355
|
+
const choice = await deps.select({ title: [deps.t("orca.pickTitle", { count: items.length })], items: items.map((entry, index) => ({ id: entry.key, label: rows[index] })), back: true });
|
|
50356
|
+
return choice.kind === "select" ? start2(choice.id) : EXIT.ok;
|
|
50357
|
+
}
|
|
50040
50358
|
let offset = 0;
|
|
50041
50359
|
while (true) {
|
|
50042
50360
|
const end = Math.min(offset + 50, items.length);
|
|
@@ -50142,7 +50460,7 @@ async function liveFacts(client, task) {
|
|
|
50142
50460
|
const claims = (Array.isArray(work2.claims) ? work2.claims : []).filter(object3).map((claim) => ({
|
|
50143
50461
|
purpose: string3(claim.purpose),
|
|
50144
50462
|
isMine: claim.isMine === true,
|
|
50145
|
-
claimId: typeof claim.claimId === "string" &&
|
|
50463
|
+
claimId: typeof claim.claimId === "string" && UUID3.test(claim.claimId) ? claim.claimId.toLowerCase() : null,
|
|
50146
50464
|
holder: object3(claim.holder) ? string3(claim.holder.text) : "",
|
|
50147
50465
|
expiresAt: string3(claim.expiresAt)
|
|
50148
50466
|
}));
|
|
@@ -50248,7 +50566,7 @@ var foreignClaim = (key, holder, expiresAt) => new CliError(
|
|
|
50248
50566
|
async function takeClaim(deps, client, task, purpose, runLabel) {
|
|
50249
50567
|
try {
|
|
50250
50568
|
const claim = (await mutate(client, WIRE.claim, { issueId: task.id, purpose, runLabel: runLabel.slice(0, 120) }, { backoffMs: deps.backoffMs })).result;
|
|
50251
|
-
return typeof claim.claimId === "string" &&
|
|
50569
|
+
return typeof claim.claimId === "string" && UUID3.test(claim.claimId) ? claim.claimId.toLowerCase() : null;
|
|
50252
50570
|
} catch (error) {
|
|
50253
50571
|
if (error instanceof ToolError && error.code === "ALREADY_CLAIMED") {
|
|
50254
50572
|
const details = object3(error.details) ? error.details : {};
|
|
@@ -51147,7 +51465,7 @@ var KIT_CAPABILITIES = Object.freeze({
|
|
|
51147
51465
|
checkout: { filePrefix: ".claude/", instructions: "CLAUDE.md", mcpFile: ".mcp.json", mcpWithType: true },
|
|
51148
51466
|
globalE1: { path: ".claude/skills/fleek-work/SKILL.md" },
|
|
51149
51467
|
verifiedWith: "Claude Code 2.1.303",
|
|
51150
|
-
initIsolation: ["2.1.310"]
|
|
51468
|
+
initIsolation: ["2.1.310", "2.1.319"]
|
|
51151
51469
|
},
|
|
51152
51470
|
// Orca terminals run Claude Code: same mechanism, Orca rendering (plan §4.4 "Orca as Claude").
|
|
51153
51471
|
orca: {
|
|
@@ -51157,7 +51475,7 @@ var KIT_CAPABILITIES = Object.freeze({
|
|
|
51157
51475
|
checkout: { filePrefix: ".claude/", instructions: "CLAUDE.md", mcpFile: ".mcp.json", mcpWithType: true },
|
|
51158
51476
|
globalE1: { path: ".claude/skills/fleek-work/SKILL.md" },
|
|
51159
51477
|
verifiedWith: "Claude Code 2.1.303 (inside Orca)",
|
|
51160
|
-
initIsolation: ["2.1.310"]
|
|
51478
|
+
initIsolation: ["2.1.310", "2.1.319"]
|
|
51161
51479
|
},
|
|
51162
51480
|
codex: {
|
|
51163
51481
|
target: "codex",
|
|
@@ -51735,7 +52053,7 @@ var USER_SKILL_MARKER = "<!-- Generated by scripts/agent-guidance/generate.mjs f
|
|
|
51735
52053
|
var USER_SKILLS = [
|
|
51736
52054
|
{
|
|
51737
52055
|
"name": "fleek-orca-coordinator",
|
|
51738
|
-
"content": "---\nname: fleek-orca-coordinator\ndescription: \"Coordinate Fleek tickets in Orca: find claimable work, claim it for this machine, start a builder in its own worktree with the project kit, review with the other model, leave gates to people and deliver to review. Use when you coordinate Orca agents for a Fleek project.\"\nmetadata:\n protocol: fleek-work-protocol/1.13\n---\n\n<!-- Generated by scripts/agent-guidance/generate.mjs from scripts/agent-guidance/protocol.json - do not edit by hand. -->\n\n# Fleek in Orca: coordinator recipe\n\nFleek holds the tickets and every human decision; Orca runs worktrees and agents. Follow the fleek-work skill for every Fleek call. Never change Orca's code or settings.\n\n## 1. Ready check\n- `fleek doctor` in the repo: Fleek MCP current for Claude Code, Codex and every Orca account, repo bound to its Fleek project. Otherwise ask the person to run the setup command from Fleek once per machine (Settings › Connections › Set up this computer: `fleek setup <code>`). Never sign in for them.\n\n## 2. Find work\n- fleek_find_work and fleek_my_work_inbox (claimable: agent-ready or assigned to your person; addressed work first); `fleek orca tasks` lists the project's open tickets. Take only status roles where agents work: intake_review, ready, analysis, design, implementation, review. Skip tickets another holder claims.\n- Read stage in fleek_get_work_context before starting a worker, then use this role table. Do not infer a role from the displayed status name or from the ticket title.\n\n| Status role | Work and delivery |\n| --- | --- |\n| intake_review | One triage agent: duplicates, criteria and readiness; no product code or PR. |\n| ready | Claim, then re-read the live stage and use its row. A claim is not permission to skip analysis or design. |\n| analysis / design | One agent: concept or design proposal with evidence; no product code or PR. |\n| implementation | Builder, other-model review, then deliver the work claim (sections 3-5). |\n| review | One reviewer with a review claim (`fleek orca start KEY --yes --agent OTHER-MODEL` takes it on the delivered branch in its own worktree): checklist, acceptance and evidence; record the verdict, then release that review claim. No builder, implementation, PR or complete_work outcome done loop. Findings go back to the existing implementation work or to the person. |\n| collecting / clarification / acceptance / customer gate | Start no builder; prepare a draft only if requested and wait for the responsible person or customer. Never decide their gate. |\n| done / cancelled | Start nothing. |\n\n- Only implementation uses sections 3-5. `fleek orca tasks` is an overview; `fleek orca pick` works only in a person's terminal and offers only server candidates without an existing work claim. Re-read the live context after claiming: availability is not a status-role decision.\n\n## 3. Claim, worktree, builder\n- `fleek orca start KEY --yes` (the core of `fleek start` for coordinators: Orca required; a new or restarted agent stays in the background, one already running comes to the front) takes or reuses the claim for this machine, creates the Orca worktree named after the key from the project's base branch with the Fleek ticket as reference and starts the agent with a first prompt naming key and claim. You run without a terminal: only `--yes` replaces the person's confirmation, without it the command refuses with CONFIRMATION_REQUIRED. Use it only for tickets your person lets you start; the web link and a person's own terminal keep asking. With the Fleek start command as Orca's agent command (`fleek setup` names it), the agent loads the project's kit. Your own claim is reused, no error. Another holder's claim or NOT_READY: pick another ticket.\n- By hand: fleek_claim_issue (purpose work, runLabel \"orca\" plus the worktree name), then `orca worktree create --name eng-123-slug --reference TICKET-URL --agent claude` from the base branch of fleek_get_project_brief.\n- The builder's task is a pointer: key, claimId, worktree, branch, role builder. Never paste ticket text, criteria or sign-in data; the agent reads them live from Fleek.\n- Models only from providers conventions.aiProviders allows (fleek_get_work_context); a customer's code never goes to another provider.\n- Card: `orca worktree set --worktree id:WORKTREE-ID --workspace-status in-progress`.\n\n## 4. Review by the other model\n- After the builder's worker_done verify its report in two reads before starting a reviewer: the fetched feature branch head equals the reported SHA and the worktree has no uncommitted changes; the test note is on the ticket when the project kit asks for one. A mismatch goes back to the builder, not to the reviewer.\n- Then start a reviewer with the other model (Claude and Codex swap; only one provider allowed: a fresh session of it) in the same worktree, role reviewer. It claims purpose review, checks criteria and checklist and records its verdict at the ticket.\n- Check the review's shape (fleek-work, In Orca, reviewer): verdict on the first line, blockers each with a reproduction, anchors only inside the reviewed range, each finding read or measured, questions for a person at the ticket. A review that misses it goes back to the reviewer once with the exact points.\n- Verdict not ready or a criterion not_met: builder round 2 in the same worktree, then review again. After two rounds ask the person.\n\n## 5. Deliver\n- Clean review: load the guidance (fleek_get_work_context), then fleek_complete_work on the work claim, outcome done, with SHA, branch, PR, checks and result, acceptance per criterion and nextStep. The ticket moves to the project's review state, never Done; check moved and toStateId.\n- A coordination or review claim that only records a status writes fleek_post_progress, not a result. One completion = one fleek_complete_work; no extra summary or analysis comment. Put the recommendation in nextStep; do not add a note about your own draft or publication request.\n- Parts open: outcome partial. Blocked: fleek_release_issue outcome not_doable. Interrupted: outcome paused. A failed dispatch is never done.\n- Card in-review with the existing result; no extra ticket comment.\n\n## 6. People decide\n- Questions only a person can answer go to the ticket (fleek_ask_question); the worker waits, the card gets `--unread`. Gates, acceptance, customer text and Done are decided by a person in Fleek, by an agent only where the project rule allows it and the person approved or gave a standing mandate. Never orca gate-resolve or a terminal yes on their behalf.\n- Answer an orca ask only when a rule or a decision recorded at the ticket settles it, and cite it. Anything else a person decides goes back as \"ask at the ticket\": the asking agent calls fleek_ask_question with the deciding person as addressee and waits. Your own person's answer in chat or terminal is recorded verbatim as an internal ticket comment (\"Answer NAME in chat, DATE: ...\"); pass it on only together with that comment, never a chat answer alone. The comment only records the factual answer of your own person; it decides no gate, customer acceptance or publication and grants or widens no mandate or agent_git_* right - those stay decisions in Fleek.\n\n## 7. Keep claims alive\n- Renew by expiresAt (about every 20 minutes) while a worker runs or waits; an Orca heartbeat is no renewal. The claim belongs to the machine, so a switched account or a usage-limit pause keeps it: renew and resume. Nobody can continue before expiry: release paused.\n- After a crash read your live claims (fleek_my_work_inbox) and `orca worktree list`, then continue on the same claim (`fleek orca start KEY --yes` restarts an ended agent) or release it. Never claim or complete twice.\n\n## 8. Limits\n- One builder per ticket, one ticket per worktree. Parallel tickets: as many as the person allows, default 2, each with its reviewer; queue the rest. QUOTA_EXCEEDED: the machine's claims are used up - finish or release one first.\n- No Orca code changes, forks or pull requests on Orca. Git effects only as far as the project brief allows.\n"
|
|
52056
|
+
"content": "---\nname: fleek-orca-coordinator\ndescription: \"Coordinate Fleek tickets in Orca: find claimable work, claim it for this machine, start a builder in its own worktree with the project kit, review with the other model, leave gates to people and deliver to review. Use when you coordinate Orca agents for a Fleek project.\"\nmetadata:\n protocol: fleek-work-protocol/1.13\n---\n\n<!-- Generated by scripts/agent-guidance/generate.mjs from scripts/agent-guidance/protocol.json - do not edit by hand. -->\n\n# Fleek in Orca: coordinator recipe\n\nFleek holds the tickets and every human decision; Orca runs worktrees and agents. Follow the fleek-work skill for every Fleek call. Never change Orca's code or settings.\n\n## 1. Ready check\n- `fleek doctor` in the repo: Fleek MCP current for Claude Code, Codex and every Orca account, repo bound to its Fleek project. Otherwise ask the person to run the setup command from Fleek once per machine (Settings › Connections › Set up this computer: `fleek setup <code>`). Never sign in for them.\n\n## 2. Find work\n- fleek_find_work and fleek_my_work_inbox (claimable: agent-ready or assigned to your person; addressed work first); `fleek orca tasks` lists the project's open tickets. Take only status roles where agents work: intake_review, ready, analysis, design, implementation, review. Skip tickets another holder claims.\n- Read stage in fleek_get_work_context before starting a worker, then use this role table. Do not infer a role from the displayed status name or from the ticket title.\n\n| Status role | Work and delivery |\n| --- | --- |\n| intake_review | One triage agent: duplicates, criteria and readiness; no product code or PR. |\n| ready | Claim, then re-read the live stage and use its row. A claim is not permission to skip analysis or design. |\n| analysis / design | One agent: concept or design proposal with evidence; no product code or PR. |\n| implementation | Builder, other-model review, then deliver the work claim (sections 3-5). |\n| review | One reviewer with a review claim (`fleek orca start KEY --yes --agent OTHER-MODEL` takes it on the delivered branch in its own worktree): checklist, acceptance and evidence; record the verdict, then release that review claim. No builder, implementation, PR or complete_work outcome done loop. Findings go back to the existing implementation work or to the person. |\n| collecting / clarification / acceptance / customer gate | Start no builder; prepare a draft only if requested and wait for the responsible person or customer. Never decide their gate. |\n| done / cancelled | Start nothing. |\n\n- Only implementation uses sections 3-5. `fleek orca tasks` is an overview; `fleek orca pick` works only in a person's terminal and offers only server candidates without an existing work claim. Re-read the live context after claiming: availability is not a status-role decision.\n\n## 3. Claim, worktree, builder\n- `fleek orca start KEY --yes` (the core of `fleek start` for coordinators: Orca required; a new or restarted agent stays in the background, one already running comes to the front) takes or reuses the claim for this machine, creates the Orca worktree named after the key from the project's base branch with the Fleek ticket as reference and starts the agent with a first prompt naming key and claim. You run without a terminal: only `--yes` replaces the person's confirmation, without it the command refuses with CONFIRMATION_REQUIRED. Use it only for tickets your person lets you start; the web link and a person's own terminal keep asking. With the Fleek start command as Orca's agent command (`fleek setup` names it), the agent loads the project's kit. Your own claim is reused, no error. Another holder's claim or NOT_READY: pick another ticket.\n- By hand: fleek_claim_issue (purpose work, runLabel \"orca\" plus the worktree name), then `orca worktree create --name eng-123-slug --reference TICKET-URL --agent claude` from the base branch of fleek_get_project_brief.\n- The builder's task is a pointer: key, claimId, worktree, branch, role builder. Never paste ticket text, criteria or sign-in data; the agent reads them live from Fleek.\n- Models only from providers conventions.aiProviders allows (fleek_get_work_context); a customer's code never goes to another provider.\n- Card: `orca worktree set --worktree id:WORKTREE-ID --workspace-status in-progress`.\n\n## 4. Review by the other model\n- After the builder's worker_done verify its report in two reads before starting a reviewer: the fetched feature branch head equals the reported SHA and the worktree has no uncommitted changes; the test note is on the ticket when the project kit asks for one. A mismatch goes back to the builder, not to the reviewer.\n- Then start a reviewer with the other model (Claude and Codex swap; only one provider allowed: a fresh session of it) in the same worktree, role reviewer. It claims purpose review, checks criteria and checklist and records its verdict at the ticket.\n- Check the review's shape (fleek-work, In Orca, reviewer): verdict on the first line, blockers each with a reproduction, anchors only inside the reviewed range, each finding read or measured, questions for a person at the ticket. A review that misses it goes back to the reviewer once with the exact points.\n- Verdict not ready or a criterion not_met: builder round 2 in the same worktree, then review again. After two rounds ask the person.\n\n## 5. Deliver\n- Clean review: load the guidance (fleek_get_work_context), then fleek_complete_work on the work claim, outcome done, with SHA, branch, PR, checks and result, acceptance per criterion and nextStep. The ticket moves to the project's review state, never Done; check moved and toStateId.\n- A coordination or review claim that only records a status writes fleek_post_progress, not a result. One completion = one fleek_complete_work; no extra summary or analysis comment. Put the recommendation in nextStep; do not add a note about your own draft or publication request.\n- Parts open: outcome partial. Blocked: fleek_release_issue outcome not_doable. Interrupted: outcome paused. A failed dispatch is never done.\n- Card in-review with the existing result; no extra ticket comment.\n\n## 6. People decide\n- Questions only a person can answer go to the ticket (fleek_ask_question); the worker waits, the card gets `--unread`. Gates, acceptance, customer text and Done are decided by a person in Fleek, by an agent only where the project rule allows it and the person approved or gave a standing mandate. Never orca gate-resolve or a terminal yes on their behalf.\n- Answer an orca ask only when a rule or a decision recorded at the ticket settles it, and cite it. Anything else a person decides goes back as \"ask at the ticket\": the asking agent calls fleek_ask_question with the deciding person as addressee and waits. Your own person's answer in chat or terminal is recorded verbatim as an internal ticket comment (\"Answer NAME in chat, DATE: ...\"); pass it on only together with that comment, never a chat answer alone. The comment only records the factual answer of your own person; it decides no gate, customer acceptance or publication and grants or widens no mandate or agent_git_* right - those stay decisions in Fleek.\n\n## 7. Keep claims alive\n- Renew by expiresAt (about every 20 minutes) while a worker runs or waits; an Orca heartbeat is no renewal. The claim belongs to the machine, so a switched account or a usage-limit pause keeps it: renew and resume. Nobody can continue before expiry: release paused. A ticket you paused stays claimable for your agent under your person's work mandate until someone else changes its status or assignee.\n- After a crash read your live claims (fleek_my_work_inbox) and `orca worktree list`, then continue on the same claim (`fleek orca start KEY --yes` restarts an ended agent) or release it. Never claim or complete twice.\n\n## 8. Limits\n- One builder per ticket, one ticket per worktree. Parallel tickets: as many as the person allows, default 2, each with its reviewer; queue the rest. QUOTA_EXCEEDED: the machine's claims are used up - finish or release one first.\n- No Orca code changes, forks or pull requests on Orca. Git effects only as far as the project brief allows.\n"
|
|
51739
52057
|
}
|
|
51740
52058
|
];
|
|
51741
52059
|
|
|
@@ -51965,8 +52283,9 @@ function initAgentArgs(prompt) {
|
|
|
51965
52283
|
JSON.stringify({ disableAllHooks: true })
|
|
51966
52284
|
];
|
|
51967
52285
|
}
|
|
51968
|
-
function initAgentEnv(env) {
|
|
51969
|
-
const
|
|
52286
|
+
function initAgentEnv(env, platform = process.platform) {
|
|
52287
|
+
const path = platform === "darwin" ? [dirname9(process.execPath), "/usr/bin"] : [dirname9(process.execPath)];
|
|
52288
|
+
const result = { PATH: path.join(delimiter2) };
|
|
51970
52289
|
for (const key of [
|
|
51971
52290
|
"HOME",
|
|
51972
52291
|
"USER",
|
|
@@ -51991,6 +52310,19 @@ function initAgentEnv(env) {
|
|
|
51991
52310
|
}
|
|
51992
52311
|
return result;
|
|
51993
52312
|
}
|
|
52313
|
+
var CLASS_LINES = 5;
|
|
52314
|
+
var FAILURE_CLASSES = [
|
|
52315
|
+
// 401 only with an HTTP/auth context, never a bare number (a file diagnosis "line 401" is not a sign-in failure)
|
|
52316
|
+
["signIn", /Not logged in|Failed to authenticate|\bauthentication[_ ](?:error|failed)\b|\b401 Unauthorized\b|\b(?:HTTP|status(?: code)?:?)\s*401\b|\b(?:OAuth )?token (?:has been |was )?(?:revoked|expired)\b|Invalid API key/i],
|
|
52317
|
+
["version", /\b(?:unknown|unrecognized) (?:option|argument|flag)\b|\bclaude update\b|\b(?:requires|needs) (?:a )?newer version\b|\bversion\b.*\b(?:not supported|unsupported|outdated)\b/i],
|
|
52318
|
+
["rateLimit", /\brate[ _-]?limit|\boverloaded(?:_error)?\b|\busage limit\b|\b429 Too Many Requests\b|\b(?:HTTP|status(?: code)?:?)\s*(?:429|529)\b/i],
|
|
52319
|
+
["network", /\b(?:ECONNREFUSED|ECONNRESET|ENOTFOUND|ETIMEDOUT|EAI_AGAIN|ENETUNREACH)\b|\bnetwork error\b|\bsocket hang up\b|\bfetch failed\b|\bunable to connect\b/i]
|
|
52320
|
+
];
|
|
52321
|
+
function classifyInitFailure(result) {
|
|
52322
|
+
const tail = `${result.stderr ?? ""}
|
|
52323
|
+
${result.stdout}`.split(/\r?\n/).filter((line) => line.trim()).slice(-CLASS_LINES).join("\n");
|
|
52324
|
+
return FAILURE_CLASSES.find(([, pattern]) => pattern.test(tail))?.[0] ?? "unknown";
|
|
52325
|
+
}
|
|
51994
52326
|
var runInitProcess = (program, args, options) => new Promise((resolve9, reject) => {
|
|
51995
52327
|
if (options.signal?.aborted) {
|
|
51996
52328
|
reject(new CliError("errors.aborted", EXIT.failed, {}, "ABORTED"));
|
|
@@ -52001,9 +52333,10 @@ var runInitProcess = (program, args, options) => new Promise((resolve9, reject)
|
|
|
52001
52333
|
env: options.env,
|
|
52002
52334
|
shell: false,
|
|
52003
52335
|
detached: process.platform !== "win32",
|
|
52004
|
-
stdio: ["ignore", "pipe", "
|
|
52336
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
52005
52337
|
});
|
|
52006
52338
|
const chunks = [];
|
|
52339
|
+
let errorTail = Buffer.alloc(0);
|
|
52007
52340
|
let bytes = 0, failure2;
|
|
52008
52341
|
const kill = (signal) => {
|
|
52009
52342
|
try {
|
|
@@ -52028,6 +52361,10 @@ var runInitProcess = (program, args, options) => new Promise((resolve9, reject)
|
|
|
52028
52361
|
if (bytes > options.maxBytes) stop(new CliError("errors.initAgentOutput", EXIT.failed, {}, "AGENT_OUTPUT_LIMIT"));
|
|
52029
52362
|
else chunks.push(chunk);
|
|
52030
52363
|
});
|
|
52364
|
+
child.stderr.on("data", (chunk) => {
|
|
52365
|
+
errorTail = Buffer.concat([errorTail, chunk]);
|
|
52366
|
+
if (errorTail.length > options.maxBytes) errorTail = errorTail.subarray(errorTail.length - options.maxBytes);
|
|
52367
|
+
});
|
|
52031
52368
|
const cleanup = () => {
|
|
52032
52369
|
clearTimeout(timer);
|
|
52033
52370
|
if (hard) clearTimeout(hard);
|
|
@@ -52040,7 +52377,7 @@ var runInitProcess = (program, args, options) => new Promise((resolve9, reject)
|
|
|
52040
52377
|
child.once("close", (code) => {
|
|
52041
52378
|
cleanup();
|
|
52042
52379
|
if (failure2) reject(failure2);
|
|
52043
|
-
else resolve9({ code: code ?? 1, stdout: Buffer.concat(chunks).toString("utf8") });
|
|
52380
|
+
else resolve9({ code: code ?? 1, stdout: Buffer.concat(chunks).toString("utf8"), stderr: errorTail.toString("utf8") });
|
|
52044
52381
|
});
|
|
52045
52382
|
});
|
|
52046
52383
|
|
|
@@ -54231,113 +54568,6 @@ var Session = class {
|
|
|
54231
54568
|
}
|
|
54232
54569
|
};
|
|
54233
54570
|
|
|
54234
|
-
// src/header.ts
|
|
54235
|
-
import { win32 as win322, posix as posix2 } from "node:path";
|
|
54236
|
-
|
|
54237
|
-
// src/uuid.ts
|
|
54238
|
-
var UUID3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
54239
|
-
function isUuid(value) {
|
|
54240
|
-
return UUID3.test(value);
|
|
54241
|
-
}
|
|
54242
|
-
function canonicalId(value) {
|
|
54243
|
-
if (!UUID3.test(value)) throw new Error("INVALID_UUID");
|
|
54244
|
-
return value.toLowerCase();
|
|
54245
|
-
}
|
|
54246
|
-
|
|
54247
|
-
// src/header.ts
|
|
54248
|
-
var LOGO2 = [" ▄██████▀", " ▄█████▀ ", " ██▀ "];
|
|
54249
|
-
var ASCII_LOGO = [" ######/", " #####/ ", " ##/ "];
|
|
54250
|
-
var BRAND = "\x1B[38;2;69;94;255m";
|
|
54251
|
-
function shouldShowHeader(positionals, options, terminal) {
|
|
54252
|
-
if (options.json || options.version || terminal.stream.isTTY !== true) return false;
|
|
54253
|
-
const active = (value) => value !== void 0 && value !== "" && value !== "0" && value !== "false";
|
|
54254
|
-
if (["CI", "CONTINUOUS_INTEGRATION", "GITHUB_ACTIONS", "BUILD_NUMBER", "TF_BUILD"].some((key) => active(terminal.env[key]))) return false;
|
|
54255
|
-
const [command, sub] = positionals;
|
|
54256
|
-
return !command || command === "help" || !!options.help || command === "setup" || command === "doctor" || command === "init" || command === "kit" && ["setup", "doctor", "pull"].includes(sub ?? "") || command === "service" && sub === "setup";
|
|
54257
|
-
}
|
|
54258
|
-
function cells(value) {
|
|
54259
|
-
let width = 0;
|
|
54260
|
-
for (const char of value) {
|
|
54261
|
-
const code = char.codePointAt(0);
|
|
54262
|
-
if (new RegExp("\\p{Mark}", "u").test(char)) continue;
|
|
54263
|
-
width += code >= 4352 && (code <= 4447 || code >= 11904 && code <= 42191 || code >= 44032 && code <= 55203 || code >= 63744 && code <= 64255 || code >= 65040 && code <= 65135 || code >= 65281 && code <= 65376 || code >= 65504 && code <= 65510 || code >= 127744) ? 2 : 1;
|
|
54264
|
-
}
|
|
54265
|
-
return width;
|
|
54266
|
-
}
|
|
54267
|
-
function fit(value, width, ascii) {
|
|
54268
|
-
if (cells(value) <= width) return value;
|
|
54269
|
-
const suffix = ascii ? "..." : "…";
|
|
54270
|
-
if (width <= suffix.length) return suffix.slice(0, Math.max(0, width));
|
|
54271
|
-
let out = "";
|
|
54272
|
-
for (const char of value) {
|
|
54273
|
-
if (cells(out + char) > width - suffix.length) break;
|
|
54274
|
-
out += char;
|
|
54275
|
-
}
|
|
54276
|
-
return out + suffix;
|
|
54277
|
-
}
|
|
54278
|
-
var safe = (value) => neutralizeLine(redact(value));
|
|
54279
|
-
function directory(context, windows, env) {
|
|
54280
|
-
const path = windows ? win322 : posix2;
|
|
54281
|
-
const home = context.home ?? userHome(env, windows ? "win32" : process.platform);
|
|
54282
|
-
const relative3 = path.relative(home, context.cwd);
|
|
54283
|
-
const inside = relative3 === "" || relative3 !== ".." && !relative3.startsWith(`..${path.sep}`) && !path.isAbsolute(relative3);
|
|
54284
|
-
return safe(inside ? relative3 ? `~${path.sep}${relative3}` : "~" : context.cwd);
|
|
54285
|
-
}
|
|
54286
|
-
function headerServer(value) {
|
|
54287
|
-
if (!value) return void 0;
|
|
54288
|
-
try {
|
|
54289
|
-
const url = new URL(value);
|
|
54290
|
-
return ["http:", "https:"].includes(url.protocol) ? url.host : void 0;
|
|
54291
|
-
} catch {
|
|
54292
|
-
return void 0;
|
|
54293
|
-
}
|
|
54294
|
-
}
|
|
54295
|
-
function renderHeader(context, terminal, t) {
|
|
54296
|
-
const windows = (terminal.platform ?? process.platform) === "win32";
|
|
54297
|
-
const ascii = windows || terminal.env.TERM === "dumb";
|
|
54298
|
-
const separator = ascii ? " - " : " · ";
|
|
54299
|
-
const requested = terminal.stream.columns ?? Number(terminal.env.COLUMNS);
|
|
54300
|
-
const columns = Number.isFinite(requested) && requested > 0 ? Math.floor(requested) : 80;
|
|
54301
|
-
const title = t("header.title", { version: safe(context.version) });
|
|
54302
|
-
const cwd = directory(context, windows, terminal.env);
|
|
54303
|
-
const parts = [context.workspace, context.project && !isUuid(context.project) ? context.project : void 0, headerServer(context.server), context.displayName].filter((value) => !!value);
|
|
54304
|
-
const details = parts.length ? parts.map(safe).join(separator) : t("header.noContext");
|
|
54305
|
-
if (columns < 60) return ["", fit([title, cwd].join(separator), columns, ascii)];
|
|
54306
|
-
const logo = ascii ? ASCII_LOGO : LOGO2;
|
|
54307
|
-
const width = Math.max(...logo.map(cells));
|
|
54308
|
-
const color = colorEnabled(terminal.env, terminal.stream);
|
|
54309
|
-
const available2 = columns - width - 6;
|
|
54310
|
-
const tagline = separator + t("header.tagline");
|
|
54311
|
-
const attribution = separator + t("header.attribution");
|
|
54312
|
-
const secondary = cells(title + tagline) <= available2 ? tagline + (cells(title + tagline + attribution) <= available2 ? attribution : "") : "";
|
|
54313
|
-
const text6 = [title, details, cwd];
|
|
54314
|
-
const rows = logo.map((row, index) => {
|
|
54315
|
-
const mark = row.padEnd(width);
|
|
54316
|
-
const label = fit(text6[index], available2, ascii);
|
|
54317
|
-
if (index === 0) {
|
|
54318
|
-
const heading = color ? `\x1B[1m${label}\x1B[22m` : label;
|
|
54319
|
-
const branding = color && secondary ? `\x1B[2m${secondary}\x1B[22m` : secondary;
|
|
54320
|
-
return `${color ? `${BRAND}${mark}\x1B[39m` : mark} ${heading}${branding}`;
|
|
54321
|
-
}
|
|
54322
|
-
const styled = color ? `\x1B[2m${label}\x1B[22m` : label;
|
|
54323
|
-
return `${color ? `${BRAND}${mark}\x1B[39m` : mark} ${styled}`;
|
|
54324
|
-
});
|
|
54325
|
-
const inner = Math.max(...rows.map((row) => cells(stripAnsi(row))));
|
|
54326
|
-
const edge = (value) => color ? `${BRAND}${value}\x1B[39m` : value;
|
|
54327
|
-
const vertical = ascii ? "|" : "│";
|
|
54328
|
-
return [
|
|
54329
|
-
"",
|
|
54330
|
-
edge(`${ascii ? "+" : "╭"}${(ascii ? "-" : "─").repeat(inner + 2)}${ascii ? "+" : "╮"}`),
|
|
54331
|
-
...rows.map((row) => `${edge(vertical)} ${row}${" ".repeat(inner - cells(stripAnsi(row)))} ${edge(vertical)}`),
|
|
54332
|
-
edge(`${ascii ? "+" : "╰"}${(ascii ? "-" : "─").repeat(inner + 2)}${ascii ? "+" : "╯"}`)
|
|
54333
|
-
];
|
|
54334
|
-
}
|
|
54335
|
-
function printHeader(out, context, terminal, t) {
|
|
54336
|
-
for (const line of renderHeader(context, terminal, t)) out.line(line);
|
|
54337
|
-
out.line();
|
|
54338
|
-
out.indentHumanOutput();
|
|
54339
|
-
}
|
|
54340
|
-
|
|
54341
54571
|
// src/project-reference.ts
|
|
54342
54572
|
async function visibleProject(client, ref) {
|
|
54343
54573
|
let cursor;
|
|
@@ -57328,6 +57558,19 @@ async function ask(ctx, lines) {
|
|
|
57328
57558
|
rl.close();
|
|
57329
57559
|
}
|
|
57330
57560
|
}
|
|
57561
|
+
var MIN_INIT_CLAUDE = "2.1.310";
|
|
57562
|
+
function olderThan(version2, minimum) {
|
|
57563
|
+
const a = version2.split(".").map(Number), b = minimum.split(".").map(Number);
|
|
57564
|
+
for (let i = 0; i < 3; i++) if (a[i] !== b[i]) return a[i] < b[i];
|
|
57565
|
+
return false;
|
|
57566
|
+
}
|
|
57567
|
+
var AGENT_FAILURE_KEYS = {
|
|
57568
|
+
signIn: "errors.initAgentSignIn",
|
|
57569
|
+
version: "errors.initAgentVersion",
|
|
57570
|
+
rateLimit: "errors.initAgentRateLimit",
|
|
57571
|
+
network: "errors.initAgentNetwork",
|
|
57572
|
+
unknown: "errors.initAgentFailed"
|
|
57573
|
+
};
|
|
57331
57574
|
async function startAgent(ctx, values, stagingDir, outputFile, timeoutMs, app) {
|
|
57332
57575
|
if (values.agent !== "claude") return false;
|
|
57333
57576
|
const program = await resolveExecutable("claude", ctx.env);
|
|
@@ -57340,7 +57583,8 @@ async function startAgent(ctx, values, stagingDir, outputFile, timeoutMs, app) {
|
|
|
57340
57583
|
const versionResult = await run2(program, ["--version"], { cwd: stagingDir, env, signal: ctx.deps.signal, timeoutMs: 1e4, maxBytes: 1024 });
|
|
57341
57584
|
const version2 = versionResult.code === 0 ? versionResult.stdout.trim().match(/^(\d+\.\d+\.\d+) \(Claude Code\)$/)?.[1] : void 0;
|
|
57342
57585
|
if (!version2 || !KIT_CAPABILITIES.claude.initIsolation?.includes(version2)) {
|
|
57343
|
-
|
|
57586
|
+
const outdated = !!version2 && olderThan(version2, MIN_INIT_CLAUDE);
|
|
57587
|
+
if (!await ask(ctx, [ctx.t(outdated ? "init.agentOutdated" : "init.agentUnknown", { version: version2 ?? "?", minimum: MIN_INIT_CLAUDE }), ctx.t("init.confirmUnknownAgent")])) return false;
|
|
57344
57588
|
}
|
|
57345
57589
|
if (!await ask(ctx, [ctx.t("init.agentBoundary"), ctx.t("init.confirmAgent")])) return false;
|
|
57346
57590
|
if (values.verbose && !ctx.json) ctx.info(ctx.out.style.cmd(neutralizeLine(program)));
|
|
@@ -57353,7 +57597,10 @@ async function startAgent(ctx, values, stagingDir, outputFile, timeoutMs, app) {
|
|
|
57353
57597
|
timeoutMs: Math.max(1, timeoutMs),
|
|
57354
57598
|
maxBytes: import_validation3.PROJECT_INIT_LIMITS.summaryBytes
|
|
57355
57599
|
}));
|
|
57356
|
-
if (result.code !== 0)
|
|
57600
|
+
if (result.code !== 0) {
|
|
57601
|
+
const diagnosis = classifyInitFailure(result);
|
|
57602
|
+
throw new CliError(AGENT_FAILURE_KEYS[diagnosis], EXIT.failed, { code: result.code, diagnosis }, "AGENT_FAILED");
|
|
57603
|
+
}
|
|
57357
57604
|
const temporary = `${outputFile}.tmp`;
|
|
57358
57605
|
await writeFile6(temporary, result.stdout, { mode: 384, flag: "wx" });
|
|
57359
57606
|
await rename4(temporary, outputFile);
|
|
@@ -57560,8 +57807,12 @@ async function initCommand(ctx, values) {
|
|
|
57560
57807
|
failed2++;
|
|
57561
57808
|
if (error instanceof CliError && error.code === "UNKNOWN_OUTCOME") unknownOutcome = true;
|
|
57562
57809
|
if (error instanceof CliError && error.exitCode === EXIT.needsLogin) throw error;
|
|
57563
|
-
|
|
57564
|
-
|
|
57810
|
+
const agentError = error instanceof CliError && /^AGENT_/.test(error.code ?? "") ? error : null;
|
|
57811
|
+
emit(ctx, { event: "error", app: app.key, code: errorCode(error), ...typeof agentError?.params.diagnosis === "string" ? { diagnosis: agentError.params.diagnosis } : {} });
|
|
57812
|
+
if (!ctx.json) {
|
|
57813
|
+
ctx.out.error(s.fail(agentError ? ctx.t(agentError.key, agentError.params) : ctx.t("init.appFailed", { app: app.key, code: errorCode(error) })));
|
|
57814
|
+
if (agentError && `${agentError.key}.next` in EN) ctx.out.error(` ${ctx.t("next.step", { command: s.cmd(ctx.t(`${agentError.key}.next`)) })}`);
|
|
57815
|
+
}
|
|
57565
57816
|
}
|
|
57566
57817
|
}
|
|
57567
57818
|
if (values.keep && !unknownOutcome) {
|
|
@@ -59233,6 +59484,20 @@ async function guidedMenu(d) {
|
|
|
59233
59484
|
out.line(`$ fleek ${args[0] === "setup" && args[1] && !args[1].startsWith("--") ? "setup <code>" : args.map(neutralizeLine).join(" ")}`);
|
|
59234
59485
|
return d.run(args, cwd2);
|
|
59235
59486
|
};
|
|
59487
|
+
const choose = async (options) => {
|
|
59488
|
+
if (d.select) return d.select(options);
|
|
59489
|
+
for (const line of [...options.context ? [options.context] : [], ...options.title ?? []]) out.line(line);
|
|
59490
|
+
for (const [i, item2] of options.items.entries()) out.line(`${i + 1} ${item2.label}${item2.hint ? ` · ${item2.hint}` : ""}`);
|
|
59491
|
+
const answer2 = (await d.ask(t("menu.choose"))).trim();
|
|
59492
|
+
if (!answer2) return { kind: "back" };
|
|
59493
|
+
const chosen = /^[1-9][0-9]*$/.test(answer2) ? options.items[Number(answer2) - 1] : void 0;
|
|
59494
|
+
if (!chosen) throw new CliError("errors.usage", EXIT.usage, {}, "USAGE");
|
|
59495
|
+
return { kind: "select", id: chosen.id };
|
|
59496
|
+
};
|
|
59497
|
+
const confirm2 = async (question) => {
|
|
59498
|
+
if (!d.select) return /^(y|yes|j|ja)$/i.test((await d.ask(`${question} ${t("menu.yesNo")}`)).trim());
|
|
59499
|
+
return isYes(await d.select(yesNoList(question, t)));
|
|
59500
|
+
};
|
|
59236
59501
|
const connect = async (setup) => {
|
|
59237
59502
|
await d.connect();
|
|
59238
59503
|
if (!setup) return EXIT.ok;
|
|
@@ -59256,53 +59521,121 @@ async function guidedMenu(d) {
|
|
|
59256
59521
|
}
|
|
59257
59522
|
return run2(["setup", code, ...language ? ["--language", language] : []]);
|
|
59258
59523
|
};
|
|
59259
|
-
out.line(t("menu.recommend", { action: d.resume ? t("menu.resume", { key: d.resume }) : t(!d.signedIn ? "menu.connect" : d.stateError ? "menu.doctor" : !d.bound ? "menu.bind" : "menu.pick") }));
|
|
59260
|
-
if (d.stateError) out.line(t("menu.stateUnreadable"));
|
|
59261
|
-
if (!d.signedIn) {
|
|
59262
|
-
out.line(`1 ${t("menu.connect")}`);
|
|
59263
|
-
out.line(`2 ${t("menu.help")}`);
|
|
59264
|
-
const choice2 = (await d.ask(t("menu.choose"))).trim();
|
|
59265
|
-
if (!choice2) return EXIT.ok;
|
|
59266
|
-
if (choice2 === "1") return connect(true);
|
|
59267
|
-
if (choice2 === "2") return run2(["help"]);
|
|
59268
|
-
throw new CliError("errors.usage", EXIT.usage, {}, "USAGE");
|
|
59269
|
-
}
|
|
59270
59524
|
let cwd;
|
|
59271
|
-
|
|
59272
|
-
|
|
59273
|
-
|
|
59274
|
-
|
|
59275
|
-
|
|
59276
|
-
|
|
59277
|
-
|
|
59278
|
-
|
|
59279
|
-
|
|
59280
|
-
|
|
59281
|
-
|
|
59282
|
-
|
|
59283
|
-
|
|
59284
|
-
|
|
59285
|
-
|
|
59525
|
+
let state;
|
|
59526
|
+
let cursor;
|
|
59527
|
+
while (true) {
|
|
59528
|
+
if (!state) {
|
|
59529
|
+
out.progress(t("menu.loading"));
|
|
59530
|
+
try {
|
|
59531
|
+
state = await d.state(cwd);
|
|
59532
|
+
} catch {
|
|
59533
|
+
state = { signedIn: false, bound: false, stateError: true, checkouts: [] };
|
|
59534
|
+
}
|
|
59535
|
+
out.progress(null);
|
|
59536
|
+
if (cwd && !state.bound && !state.stateError) {
|
|
59537
|
+
cwd = void 0;
|
|
59538
|
+
continue;
|
|
59539
|
+
}
|
|
59540
|
+
}
|
|
59541
|
+
const current2 = state;
|
|
59542
|
+
const recommended = (id2, wanted2) => id2 === wanted2 ? { hint: t("menu.recommended") } : {};
|
|
59543
|
+
const chooser2 = current2.signedIn && !current2.bound && !current2.stateError;
|
|
59544
|
+
const canSwitch = !chooser2 && !!cwd;
|
|
59545
|
+
const wanted = !current2.signedIn ? "connect" : current2.resume ? "resume" : current2.stateError ? "doctor" : "pick";
|
|
59546
|
+
const items = !current2.signedIn ? [{ id: "connect", label: t("menu.connect"), ...recommended("connect", wanted) }, { id: "help", label: t("menu.help") }, { id: "quit", label: t("menu.quit") }] : chooser2 ? [
|
|
59547
|
+
...current2.checkouts.map((checkout, i) => ({ id: `checkout:${i}`, label: checkout.label ?? checkout.path, ...checkout.project ? { hint: checkout.project } : {} })),
|
|
59548
|
+
{ id: "connect", label: t("menu.setupComputer") },
|
|
59549
|
+
{ id: "help", label: t("menu.help") },
|
|
59550
|
+
{ id: "quit", label: t("menu.quit") }
|
|
59551
|
+
] : [
|
|
59552
|
+
...current2.resume ? [{ id: "resume", label: t("menu.resume", { key: current2.resume }), ...recommended("resume", wanted) }] : [],
|
|
59553
|
+
{ id: "pick", label: t("menu.pick"), ...recommended("pick", wanted) },
|
|
59554
|
+
{ id: "continue", label: t("menu.continue") },
|
|
59555
|
+
{ id: "doctor", label: t("menu.doctor"), ...recommended("doctor", wanted) },
|
|
59556
|
+
{ id: "connections", label: t("menu.connections") },
|
|
59557
|
+
...canSwitch ? [{ id: "switch", label: t("menu.switchCheckout") }] : [],
|
|
59558
|
+
{ id: "help", label: t("menu.help") },
|
|
59559
|
+
{ id: "quit", label: t("menu.quit") }
|
|
59560
|
+
];
|
|
59561
|
+
const title = [
|
|
59562
|
+
...chooser2 ? [t("menu.checkoutTitle")] : [],
|
|
59563
|
+
...current2.stateError && current2.signedIn ? [t("menu.stateUnreadable")] : [],
|
|
59564
|
+
...current2.repair && current2.signedIn && !chooser2 ? [t("menu.fix", { command: `fleek ${repair.join(" ")}` })] : []
|
|
59565
|
+
];
|
|
59566
|
+
let choice;
|
|
59567
|
+
try {
|
|
59568
|
+
choice = await choose({ ...current2.context ? { context: current2.context } : {}, title, items, initial: cursor && items.some((item2) => item2.id === cursor) ? cursor : wanted, quit: true, back: canSwitch });
|
|
59569
|
+
} catch (error) {
|
|
59570
|
+
d.report(error);
|
|
59571
|
+
out.line();
|
|
59572
|
+
continue;
|
|
59573
|
+
}
|
|
59574
|
+
if (choice.kind !== "select") {
|
|
59575
|
+
if (choice.kind === "back" && canSwitch) {
|
|
59576
|
+
cwd = void 0;
|
|
59577
|
+
state = void 0;
|
|
59578
|
+
cursor = void 0;
|
|
59579
|
+
continue;
|
|
59580
|
+
}
|
|
59286
59581
|
return EXIT.ok;
|
|
59287
|
-
case "1":
|
|
59288
|
-
return run2(["start", "--mine"], cwd);
|
|
59289
|
-
case "2": {
|
|
59290
|
-
const key = (await d.ask(d.resume ? t("menu.ticketDefault", { key: d.resume }) : t("menu.ticket"))).trim().toUpperCase() || d.resume;
|
|
59291
|
-
if (!key) return EXIT.ok;
|
|
59292
|
-
if (!/^[A-Z0-9]{2,10}-[1-9][0-9]*$/.test(key)) throw new CliError("errors.usage", EXIT.usage, {}, "USAGE");
|
|
59293
|
-
return run2(["start", key], cwd);
|
|
59294
|
-
}
|
|
59295
|
-
case "3": {
|
|
59296
|
-
const code = await run2(["doctor"], cwd);
|
|
59297
|
-
if ((code !== EXIT.ok || d.repair || d.stateError) && /^(y|yes|j|ja)$/i.test((await d.ask(t("menu.repair", { command: `fleek ${repair.join(" ")}` }))).trim())) return run2(repair, cwd);
|
|
59298
|
-
return code;
|
|
59299
59582
|
}
|
|
59300
|
-
|
|
59301
|
-
|
|
59302
|
-
|
|
59303
|
-
|
|
59304
|
-
|
|
59305
|
-
|
|
59583
|
+
const id = choice.id;
|
|
59584
|
+
if (id === "quit") return EXIT.ok;
|
|
59585
|
+
cursor = id;
|
|
59586
|
+
if (id === "switch") {
|
|
59587
|
+
cwd = void 0;
|
|
59588
|
+
state = void 0;
|
|
59589
|
+
cursor = void 0;
|
|
59590
|
+
continue;
|
|
59591
|
+
}
|
|
59592
|
+
if (id.startsWith("checkout:")) {
|
|
59593
|
+
cwd = current2.checkouts[Number(id.slice(9))]?.path;
|
|
59594
|
+
state = void 0;
|
|
59595
|
+
cursor = void 0;
|
|
59596
|
+
continue;
|
|
59597
|
+
}
|
|
59598
|
+
let refresh = true, code = EXIT.ok;
|
|
59599
|
+
try {
|
|
59600
|
+
switch (id) {
|
|
59601
|
+
case "connect":
|
|
59602
|
+
code = await connect(true);
|
|
59603
|
+
break;
|
|
59604
|
+
case "resume":
|
|
59605
|
+
code = await run2(["start", current2.resume], cwd);
|
|
59606
|
+
break;
|
|
59607
|
+
case "pick":
|
|
59608
|
+
code = await run2(["start", "--mine"], cwd);
|
|
59609
|
+
break;
|
|
59610
|
+
case "continue": {
|
|
59611
|
+
const key = (await d.ask(current2.resume ? t("menu.ticketDefault", { key: current2.resume }) : t("menu.ticket"))).trim().toUpperCase() || current2.resume;
|
|
59612
|
+
if (!key) {
|
|
59613
|
+
refresh = false;
|
|
59614
|
+
break;
|
|
59615
|
+
}
|
|
59616
|
+
if (!/^[A-Z0-9]{2,10}-[1-9][0-9]*$/.test(key)) throw new CliError("errors.usage", EXIT.usage, {}, "USAGE");
|
|
59617
|
+
code = await run2(["start", key], cwd);
|
|
59618
|
+
break;
|
|
59619
|
+
}
|
|
59620
|
+
case "doctor":
|
|
59621
|
+
code = await run2(["doctor"], cwd);
|
|
59622
|
+
if (!d.leaving?.() && (code !== EXIT.ok || current2.repair || current2.stateError) && await confirm2(t("menu.repair", { command: `fleek ${repair.join(" ")}` }))) code = await run2(repair, cwd);
|
|
59623
|
+
break;
|
|
59624
|
+
case "connections":
|
|
59625
|
+
refresh = false;
|
|
59626
|
+
code = await connect(false);
|
|
59627
|
+
break;
|
|
59628
|
+
case "help":
|
|
59629
|
+
refresh = false;
|
|
59630
|
+
code = await run2(["help"]);
|
|
59631
|
+
break;
|
|
59632
|
+
}
|
|
59633
|
+
} catch (error) {
|
|
59634
|
+
d.report(error);
|
|
59635
|
+
}
|
|
59636
|
+
if (d.leaving?.()) return code;
|
|
59637
|
+
out.line();
|
|
59638
|
+
if (refresh) state = void 0;
|
|
59306
59639
|
}
|
|
59307
59640
|
}
|
|
59308
59641
|
|
|
@@ -59676,6 +60009,10 @@ var Context = class {
|
|
|
59676
60009
|
fetch;
|
|
59677
60010
|
now;
|
|
59678
60011
|
headerShown = false;
|
|
60012
|
+
/** Bare `fleek` is an application: an update hint once, and these two end it after the current action. */
|
|
60013
|
+
updateChecked = false;
|
|
60014
|
+
agentRan = false;
|
|
60015
|
+
appQuit = false;
|
|
59679
60016
|
store;
|
|
59680
60017
|
boundProfile;
|
|
59681
60018
|
/** The look of human lines (colours only for a TTY, never with --json). */
|
|
@@ -59979,7 +60316,7 @@ async function confirmLocal(ctx, lines) {
|
|
|
59979
60316
|
const rl = createInterface2({ input: process.stdin, output: process.stderr });
|
|
59980
60317
|
try {
|
|
59981
60318
|
for (const line of lines.slice(0, -1)) ctx.out.error(line);
|
|
59982
|
-
const answer2 = await rl
|
|
60319
|
+
const answer2 = await askLine(rl, `${ctx.out.render(ctx.s.question(lines.at(-1) ?? ""), "err")} `);
|
|
59983
60320
|
return /^(?:j|ja|y|yes)$/i.test(answer2.trim());
|
|
59984
60321
|
} finally {
|
|
59985
60322
|
rl.close();
|
|
@@ -60339,7 +60676,8 @@ async function dispatch(ctx, positionals, values, exec, passthrough) {
|
|
|
60339
60676
|
displayName: profile?.needsLogin ? void 0 : profile?.displayName
|
|
60340
60677
|
}, terminal, ctx.t);
|
|
60341
60678
|
}
|
|
60342
|
-
if (!["update", "uninstall", "mcp", "listen", "help", "login", "setup"].includes(command ?? "") && !(command === "kit" && sub === "run") && !values.help) {
|
|
60679
|
+
if (!ctx.updateChecked && !["update", "uninstall", "mcp", "listen", "help", "login", "setup"].includes(command ?? "") && !(command === "kit" && sub === "run") && !values.help) {
|
|
60680
|
+
ctx.updateChecked = true;
|
|
60343
60681
|
await updateHint({
|
|
60344
60682
|
configDir: ctx.configDir,
|
|
60345
60683
|
env: ctx.env,
|
|
@@ -60353,47 +60691,19 @@ async function dispatch(ctx, positionals, values, exec, passthrough) {
|
|
|
60353
60691
|
}, ctx.deps.isTTY ?? (process.stderr.isTTY === true && process.stdin.isTTY === true));
|
|
60354
60692
|
}
|
|
60355
60693
|
if (!command && !values.help && !ctx.json && (ctx.deps.isTTY ?? (process.stdin.isTTY === true && (ctx.deps.stdout ?? process.stdout).isTTY === true))) {
|
|
60356
|
-
let
|
|
60357
|
-
const found = await resolveBinding(ctx.profiles, ctx.configDir, { flag: ctx.profileFlag, env: ctx.env, cwd: ctx.deps.cwd ?? process.cwd(), allowCurrent: true }).catch(() => {
|
|
60358
|
-
stateError = true;
|
|
60359
|
-
return null;
|
|
60360
|
-
});
|
|
60361
|
-
const profile = found?.profile ?? await ctx.profiles.current().catch(() => null);
|
|
60362
|
-
const checkouts = profile ? await new CheckoutIndex(ctx.configDir, profile.key).entries().catch(() => {
|
|
60363
|
-
stateError = true;
|
|
60364
|
-
return [];
|
|
60365
|
-
}) : [];
|
|
60366
|
-
const domain = profile && found?.projectId ? new KitDomain(ctx.configDir, profile.key, found.projectId) : null;
|
|
60367
|
-
let kitNeedsRepair = false;
|
|
60368
|
-
if (domain) {
|
|
60369
|
-
try {
|
|
60370
|
-
kitNeedsRepair = !await domain.current() && await domain.pulledAt() === null;
|
|
60371
|
-
} catch {
|
|
60372
|
-
stateError = true;
|
|
60373
|
-
kitNeedsRepair = true;
|
|
60374
|
-
}
|
|
60375
|
-
}
|
|
60376
|
-
const handler = await inspectSetupHandler(kitContext(ctx, values)).catch(() => {
|
|
60377
|
-
stateError = true;
|
|
60378
|
-
return null;
|
|
60379
|
-
});
|
|
60380
|
-
const repair = handler?.state === "missing" || kitNeedsRepair ? ["kit", "setup"] : void 0;
|
|
60381
|
-
const resume = profile && !profile.needsLogin && found?.projectId ? await ctx.session().then(async ({ client }) => {
|
|
60382
|
-
const inbox = (await client.callTool(WIRE.inbox, { limit: 25, kinds: ["claim"], teamId: found.projectId })).structured;
|
|
60383
|
-
const rows = Array.isArray(inbox.items) ? inbox.items : [];
|
|
60384
|
-
return rows.find((row) => row.kind === "claim" && typeof row.identifier === "string" && /^[A-Z0-9]{2,10}-[1-9][0-9]*$/.test(row.identifier))?.identifier;
|
|
60385
|
-
}).catch(() => void 0) : void 0;
|
|
60694
|
+
let leaving = false;
|
|
60386
60695
|
return guidedMenu({
|
|
60387
|
-
resume,
|
|
60388
|
-
stateError,
|
|
60389
60696
|
out: ctx.out,
|
|
60390
|
-
t: ctx.t,
|
|
60697
|
+
t: (key, params) => ctx.t(key, params),
|
|
60391
60698
|
ask: orcaDeps(ctx).ask,
|
|
60392
|
-
|
|
60393
|
-
|
|
60394
|
-
|
|
60395
|
-
|
|
60699
|
+
...selectFor(ctx),
|
|
60700
|
+
state: (cwd) => menuState(ctx, values, cwd),
|
|
60701
|
+
leaving: () => leaving,
|
|
60702
|
+
report: (error) => {
|
|
60703
|
+
reportFailure(ctx.out, ctx.t, error, false);
|
|
60704
|
+
},
|
|
60396
60705
|
connect: async () => {
|
|
60706
|
+
const profile = await ctx.profiles.current().catch(() => null);
|
|
60397
60707
|
const origin = profile ? webOrigin(profile) : "https://app.onfleek.app";
|
|
60398
60708
|
if (!origin) {
|
|
60399
60709
|
ctx.out.line(ctx.t("menu.setupExternal"));
|
|
@@ -60407,7 +60717,13 @@ async function dispatch(ctx, positionals, values, exec, passthrough) {
|
|
|
60407
60717
|
const target = cwd ? new Context({ ...ctx.deps, cwd }, false, ctx.profileFlag, ctx.languageFlag) : ctx;
|
|
60408
60718
|
const parsed = parseArgs({ args, options: OPTIONS, allowPositionals: true });
|
|
60409
60719
|
target.headerShown = ctx.headerShown;
|
|
60410
|
-
|
|
60720
|
+
target.updateChecked = true;
|
|
60721
|
+
if (target !== ctx && ctx.headerShown) target.out.indentHumanOutput();
|
|
60722
|
+
try {
|
|
60723
|
+
return await dispatch(target, parsed.positionals, { profile: values.profile, language: values.language, ...parsed.values, yes: false }, null, null);
|
|
60724
|
+
} finally {
|
|
60725
|
+
leaving = target.agentRan || target.appQuit;
|
|
60726
|
+
}
|
|
60411
60727
|
}
|
|
60412
60728
|
});
|
|
60413
60729
|
}
|
|
@@ -60695,6 +61011,82 @@ async function mcpProxy(ctx, args, values) {
|
|
|
60695
61011
|
...ctx.deps.proxyRetryDelaysMs ? { retryDelaysMs: ctx.deps.proxyRetryDelaysMs } : {}
|
|
60696
61012
|
});
|
|
60697
61013
|
}
|
|
61014
|
+
function selectFor(ctx) {
|
|
61015
|
+
const stdin = ctx.deps.stdin ?? process.stdin, stdout = ctx.deps.stdout ?? process.stdout;
|
|
61016
|
+
if (ctx.json || !isKeyInput(stdin) || stdout.isTTY !== true || ctx.env.TERM === "dumb") return {};
|
|
61017
|
+
return { select: async (options) => {
|
|
61018
|
+
const result = await selectList({ stdin, stdout, out: ctx.out, t: ctx.t }, options);
|
|
61019
|
+
if (result.kind === "abort") ctx.appQuit = true;
|
|
61020
|
+
return result;
|
|
61021
|
+
} };
|
|
61022
|
+
}
|
|
61023
|
+
function askLine(rl, question) {
|
|
61024
|
+
return new Promise((resolve9, reject) => {
|
|
61025
|
+
rl.once("close", () => resolve9(""));
|
|
61026
|
+
rl.question(question).then(resolve9, reject);
|
|
61027
|
+
});
|
|
61028
|
+
}
|
|
61029
|
+
var RESUME_READ_MS = 3e3;
|
|
61030
|
+
async function menuState(ctx, values, cwd) {
|
|
61031
|
+
let stateError = false;
|
|
61032
|
+
const folder = cwd ?? ctx.deps.cwd ?? process.cwd();
|
|
61033
|
+
const found = await resolveBinding(ctx.profiles, ctx.configDir, { flag: ctx.profileFlag, env: ctx.env, cwd: folder, allowCurrent: true }).catch(() => {
|
|
61034
|
+
stateError = true;
|
|
61035
|
+
return null;
|
|
61036
|
+
});
|
|
61037
|
+
const profile = found?.profile ?? await ctx.profiles.current().catch(() => null);
|
|
61038
|
+
if (profile?.language && !ctx.languageFlag) ctx.t = translator(profile.language);
|
|
61039
|
+
const keys = profile ? new ProjectKeyIndex(ctx.configDir, profile.key) : null;
|
|
61040
|
+
const keyOf = async (project2) => await keys?.keyFor(project2).catch(() => null) ?? void 0;
|
|
61041
|
+
const entries = profile ? await new CheckoutIndex(ctx.configDir, profile.key).entries().catch(() => {
|
|
61042
|
+
stateError = true;
|
|
61043
|
+
return [];
|
|
61044
|
+
}) : [];
|
|
61045
|
+
const checkouts = (await Promise.all(entries.map(async ([path, project2]) => {
|
|
61046
|
+
if (!await stat16(path).then((info) => info.isDirectory(), () => false)) return null;
|
|
61047
|
+
const key = await keyOf(project2);
|
|
61048
|
+
return { path, label: displayPath(path, ctx.home, ctx.env), ...key ? { project: key } : {} };
|
|
61049
|
+
}))).filter((entry) => entry !== null);
|
|
61050
|
+
const domain = profile && found?.projectId ? new KitDomain(ctx.configDir, profile.key, found.projectId) : null;
|
|
61051
|
+
let kitNeedsRepair = false;
|
|
61052
|
+
if (domain) {
|
|
61053
|
+
try {
|
|
61054
|
+
kitNeedsRepair = !await domain.current() && await domain.pulledAt() === null;
|
|
61055
|
+
} catch {
|
|
61056
|
+
stateError = true;
|
|
61057
|
+
kitNeedsRepair = true;
|
|
61058
|
+
}
|
|
61059
|
+
}
|
|
61060
|
+
const handler = await inspectSetupHandler(kitContext(ctx, values)).catch(() => {
|
|
61061
|
+
stateError = true;
|
|
61062
|
+
return null;
|
|
61063
|
+
});
|
|
61064
|
+
const signedIn = !!profile && !profile.needsLogin;
|
|
61065
|
+
let resume;
|
|
61066
|
+
if (signedIn && found?.projectId) {
|
|
61067
|
+
const read2 = ctx.sessionFor(profile).then(async ({ client }) => {
|
|
61068
|
+
const inbox = (await client.callTool(WIRE.inbox, { limit: 25, kinds: ["claim"], teamId: found.projectId })).structured;
|
|
61069
|
+
const rows = Array.isArray(inbox.items) ? inbox.items : [];
|
|
61070
|
+
return rows.find((row) => row.kind === "claim" && typeof row.identifier === "string" && /^[A-Z0-9]{2,10}-[1-9][0-9]*$/.test(row.identifier))?.identifier;
|
|
61071
|
+
}).catch(() => void 0);
|
|
61072
|
+
let timer;
|
|
61073
|
+
resume = await Promise.race([read2, new Promise((resolve9) => {
|
|
61074
|
+
timer = setTimeout(() => resolve9(void 0), RESUME_READ_MS);
|
|
61075
|
+
})]);
|
|
61076
|
+
clearTimeout(timer);
|
|
61077
|
+
}
|
|
61078
|
+
const project = found?.projectId ? await keyOf(found.projectId) : void 0;
|
|
61079
|
+
const context = signedIn ? [profile.workspace.name, project, displayPath(folder, ctx.home, ctx.env)].filter(Boolean).map((part) => neutralizeLine(part)).join(" · ") : void 0;
|
|
61080
|
+
return {
|
|
61081
|
+
signedIn,
|
|
61082
|
+
bound: !!found?.projectId,
|
|
61083
|
+
stateError,
|
|
61084
|
+
checkouts,
|
|
61085
|
+
...resume ? { resume } : {},
|
|
61086
|
+
...context ? { context } : {},
|
|
61087
|
+
...handler?.state === "missing" || kitNeedsRepair ? { repair: true } : {}
|
|
61088
|
+
};
|
|
61089
|
+
}
|
|
60698
61090
|
function orcaDeps(ctx) {
|
|
60699
61091
|
return {
|
|
60700
61092
|
out: ctx.out,
|
|
@@ -60713,11 +61105,12 @@ function orcaDeps(ctx) {
|
|
|
60713
61105
|
const { createInterface: createInterface2 } = await import("node:readline/promises");
|
|
60714
61106
|
const rl = createInterface2({ input: process.stdin, output: ctx.json ? process.stderr : process.stdout });
|
|
60715
61107
|
try {
|
|
60716
|
-
return await rl
|
|
61108
|
+
return await askLine(rl, `${ctx.out.render(ctx.out.style.question(question), ctx.json ? "err" : "out")} `);
|
|
60717
61109
|
} finally {
|
|
60718
61110
|
rl.close();
|
|
60719
61111
|
}
|
|
60720
61112
|
}),
|
|
61113
|
+
...selectFor(ctx),
|
|
60721
61114
|
...ctx.deps.mutationBackoffMs !== void 0 ? { backoffMs: ctx.deps.mutationBackoffMs } : {}
|
|
60722
61115
|
};
|
|
60723
61116
|
}
|
|
@@ -60734,7 +61127,11 @@ async function start(ctx, key, values) {
|
|
|
60734
61127
|
...orcaDeps(ctx),
|
|
60735
61128
|
...ctx.deps.linkDialog ? { dialog: ctx.deps.linkDialog } : {},
|
|
60736
61129
|
kitReady: async (agent, found) => !!(await new KitDomain(ctx.configDir, found.profile.key, found.projectId).current())?.state.targets[agent],
|
|
60737
|
-
runAgent: (agent, args, found) =>
|
|
61130
|
+
runAgent: async (agent, args, found) => {
|
|
61131
|
+
const code = await kitRun(kitContext(ctx, values, { profile: found.profile, projectId: found.projectId, source: "repo", root: found.root }), agent, { project: found.projectId }, args);
|
|
61132
|
+
ctx.agentRan = code !== 127;
|
|
61133
|
+
return code;
|
|
61134
|
+
}
|
|
60738
61135
|
};
|
|
60739
61136
|
return key ? fleekStart(deps, key, own4) : orcaPick(deps, own4, (chosen) => fleekStart(deps, chosen, own4));
|
|
60740
61137
|
}
|
|
@@ -61025,6 +61422,31 @@ async function setupDeveloper(ctx, code, values) {
|
|
|
61025
61422
|
}
|
|
61026
61423
|
}, code, values);
|
|
61027
61424
|
}
|
|
61425
|
+
function reportFailure(out, t, error, json2) {
|
|
61426
|
+
const errno = error?.code;
|
|
61427
|
+
const failure2 = error instanceof CliError ? error : typeof errno === "string" && /^E[A-Z]{2,16}$/.test(errno) ? new CliError("errors.internalCode", EXIT.failed, { code: errno }, "INTERNAL") : new CliError("errors.internal", EXIT.failed, {}, "INTERNAL");
|
|
61428
|
+
if (json2) out.json({ error: failure2.code ?? failure2.key, ...Object.keys(failure2.params).length ? { details: failure2.params } : {} });
|
|
61429
|
+
else {
|
|
61430
|
+
const params = Object.fromEntries(Object.entries(failure2.params).map(([key, value]) => [key, typeof value === "string" ? neutralizeLine(value) : value]));
|
|
61431
|
+
let friendlyKey = failure2 instanceof ToolError && ["RATE_LIMITED", "ACCESS_DENIED", "CONFLICT", "TRANSITION_DENIED"].includes(failure2.code ?? "") ? `errors.server.${failure2.code}` : failure2.key;
|
|
61432
|
+
if (failure2.code === "KIT_INVALID" || failure2.code === "KIT_UNSIGNED") {
|
|
61433
|
+
const reason = String(failure2.params.reason ?? "");
|
|
61434
|
+
const kind = kitRefusalCategory(failure2.code, reason);
|
|
61435
|
+
friendlyKey = `errors.kitRefused.${kind}`;
|
|
61436
|
+
}
|
|
61437
|
+
out.error(out.style.fail(redact(t(friendlyKey, params))));
|
|
61438
|
+
if (failure2 instanceof ToolError && failure2.code === "TRANSITION_DENIED") {
|
|
61439
|
+
const details = failure2.details;
|
|
61440
|
+
const key = typeof details?.reason === "string" ? `errors.transition.${details.reason}` : "";
|
|
61441
|
+
if (Object.hasOwn(EN, key)) out.error(t(key));
|
|
61442
|
+
}
|
|
61443
|
+
const suggestion = failure2.suggestion;
|
|
61444
|
+
if (suggestion) out.error(t("errors.didYouMean", { command: out.style.cmd(suggestion) }));
|
|
61445
|
+
if (failure2.code === "KIT_INVALID" || failure2.code === "KIT_UNSIGNED") out.error(out.style.dim(redact(t("errors.kitReason", { ...params, reason: params.reason ?? failure2.code }))));
|
|
61446
|
+
if (`${friendlyKey}.next` in EN) out.error(` ${t("next.step", { command: out.style.cmd(redact(t(`${friendlyKey}.next`, params))) })}`);
|
|
61447
|
+
}
|
|
61448
|
+
return failure2;
|
|
61449
|
+
}
|
|
61028
61450
|
async function main(argv, deps = {}) {
|
|
61029
61451
|
const env = deps.env ?? process.env;
|
|
61030
61452
|
let t = translator(locale(env));
|
|
@@ -61055,30 +61477,7 @@ async function main(argv, deps = {}) {
|
|
|
61055
61477
|
context = new Context(deps, json2, parsed.values.profile, parsed.values.language === "en" || parsed.values.language === "de" ? parsed.values.language : void 0);
|
|
61056
61478
|
return await dispatch(context, parsed.positionals, parsed.values, exec, passthrough);
|
|
61057
61479
|
} catch (error) {
|
|
61058
|
-
|
|
61059
|
-
const errorOut = context?.out ?? out;
|
|
61060
|
-
const errno = error?.code;
|
|
61061
|
-
const failure2 = error instanceof CliError ? error : typeof errno === "string" && /^E[A-Z]{2,16}$/.test(errno) ? new CliError("errors.internalCode", EXIT.failed, { code: errno }, "INTERNAL") : new CliError("errors.internal", EXIT.failed, {}, "INTERNAL");
|
|
61062
|
-
if (json2) errorOut.json({ error: failure2.code ?? failure2.key, ...Object.keys(failure2.params).length ? { details: failure2.params } : {} });
|
|
61063
|
-
else {
|
|
61064
|
-
const params = Object.fromEntries(Object.entries(failure2.params).map(([key, value]) => [key, typeof value === "string" ? neutralizeLine(value) : value]));
|
|
61065
|
-
let friendlyKey = failure2 instanceof ToolError && ["RATE_LIMITED", "ACCESS_DENIED", "CONFLICT", "TRANSITION_DENIED"].includes(failure2.code ?? "") ? `errors.server.${failure2.code}` : failure2.key;
|
|
61066
|
-
if (failure2.code === "KIT_INVALID" || failure2.code === "KIT_UNSIGNED") {
|
|
61067
|
-
const reason = String(failure2.params.reason ?? "");
|
|
61068
|
-
const kind = kitRefusalCategory(failure2.code, reason);
|
|
61069
|
-
friendlyKey = `errors.kitRefused.${kind}`;
|
|
61070
|
-
}
|
|
61071
|
-
errorOut.error(errorOut.style.fail(redact(t(friendlyKey, params))));
|
|
61072
|
-
if (failure2 instanceof ToolError && failure2.code === "TRANSITION_DENIED") {
|
|
61073
|
-
const details = failure2.details;
|
|
61074
|
-
const key = typeof details?.reason === "string" ? `errors.transition.${details.reason}` : "";
|
|
61075
|
-
if (Object.hasOwn(EN, key)) errorOut.error(t(key));
|
|
61076
|
-
}
|
|
61077
|
-
const suggestion = failure2.suggestion;
|
|
61078
|
-
if (suggestion) errorOut.error(t("errors.didYouMean", { command: errorOut.style.cmd(suggestion) }));
|
|
61079
|
-
if (failure2.code === "KIT_INVALID" || failure2.code === "KIT_UNSIGNED") errorOut.error(errorOut.style.dim(redact(t("errors.kitReason", { ...params, reason: params.reason ?? failure2.code }))));
|
|
61080
|
-
if (`${friendlyKey}.next` in EN) errorOut.error(` ${t("next.step", { command: errorOut.style.cmd(redact(t(`${friendlyKey}.next`, params))) })}`);
|
|
61081
|
-
}
|
|
61480
|
+
const failure2 = reportFailure(context?.out ?? out, context?.t ?? t, error, json2);
|
|
61082
61481
|
if (["listen", "mcp"].includes(commandName ?? "") && failure2.code === "ACCESS_DENIED") return EXIT.accessDenied;
|
|
61083
61482
|
return failure2.exitCode;
|
|
61084
61483
|
}
|