@logic-joe/fleek 0.2.15 → 0.2.17
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 +651 -259
- 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.17";
|
|
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) {
|
|
@@ -31680,7 +31681,7 @@ var require_secret_shape = __commonJS({
|
|
|
31680
31681
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31681
31682
|
exports.SECRET_SHAPE_LIMITS = void 0;
|
|
31682
31683
|
exports.validUrlHost = validUrlHost;
|
|
31683
|
-
exports.detectSecretShape =
|
|
31684
|
+
exports.detectSecretShape = detectSecretShape2;
|
|
31684
31685
|
exports.SECRET_SHAPE_LIMITS = { highEntropyMinRun: 32, highEntropyMinBits: 4.2, highEntropyMinSwitchRate: 0.35 };
|
|
31685
31686
|
var TOKEN_PREFIXES = [
|
|
31686
31687
|
["ghp_", 30],
|
|
@@ -31982,7 +31983,7 @@ var require_secret_shape = __commonJS({
|
|
|
31982
31983
|
}
|
|
31983
31984
|
return -1;
|
|
31984
31985
|
}
|
|
31985
|
-
function
|
|
31986
|
+
function detectSecretShape2(text6) {
|
|
31986
31987
|
if (text6.length === 0)
|
|
31987
31988
|
return null;
|
|
31988
31989
|
if (text6.includes("-----BEGIN "))
|
|
@@ -32669,7 +32670,7 @@ var require_knowledge_skeleton = __commonJS({
|
|
|
32669
32670
|
"../validation/dist/agent-platform/knowledge-skeleton.js"(exports) {
|
|
32670
32671
|
"use strict";
|
|
32671
32672
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32672
|
-
exports.PROJECT_CORE_PAGES = exports.DEVELOPMENT_PROFILE_KEYS = void 0;
|
|
32673
|
+
exports.PROJECT_CORE_PAGES = exports.DEVELOPMENT_PROFILE_KEYS = exports.AGENT_GIT_KEYS = exports.AGENT_GIT_DEFAULTS = void 0;
|
|
32673
32674
|
exports.exampleProfileSchema = exampleProfileSchema;
|
|
32674
32675
|
exports.withMissingExampleFields = withMissingExampleFields;
|
|
32675
32676
|
exports.skeletonLabels = skeletonLabels;
|
|
@@ -32693,7 +32694,8 @@ var require_knowledge_skeleton = __commonJS({
|
|
|
32693
32694
|
// `fleek_get_project_brief` (never guessed; forms written as examples, without angle brackets: the agent reads them through
|
|
32694
32695
|
// the text owner). Env files only by name, never credentials.
|
|
32695
32696
|
...DEVELOPMENT_FIELDS.map(([key, de, en, type]) => developmentField(key, t(L(de, en)), type)),
|
|
32696
|
-
// "Agenten dürfen (Git)": true = without asking;
|
|
32697
|
+
// "Agenten dürfen (Git)": true = without asking; false = ask first. Empty = the code default `AGENT_GIT_DEFAULTS` (bundle R A8;
|
|
32698
|
+
// the brief returns the effective value with its source) - the profile field is never pre-set
|
|
32697
32699
|
...AGENT_GIT_FIELDS.map(([key, de, en]) => ({ key, label: t(L(de, en)), type: "bool" }))
|
|
32698
32700
|
]
|
|
32699
32701
|
};
|
|
@@ -32730,6 +32732,17 @@ var require_knowledge_skeleton = __commonJS({
|
|
|
32730
32732
|
["agent_git_delete_remote", "Agenten dürfen Remote-Branch löschen", "Agents may delete the remote branch"],
|
|
32731
32733
|
["agent_git_stop_servers", "Agenten dürfen fremde Server stoppen", "Agents may stop other servers"]
|
|
32732
32734
|
];
|
|
32735
|
+
exports.AGENT_GIT_DEFAULTS = Object.freeze({
|
|
32736
|
+
agent_git_commit: true,
|
|
32737
|
+
agent_git_push: true,
|
|
32738
|
+
// own feature branch only
|
|
32739
|
+
agent_git_open_mr: true,
|
|
32740
|
+
agent_git_merge: false,
|
|
32741
|
+
agent_git_delete_local: false,
|
|
32742
|
+
agent_git_delete_remote: false,
|
|
32743
|
+
agent_git_stop_servers: false
|
|
32744
|
+
});
|
|
32745
|
+
exports.AGENT_GIT_KEYS = AGENT_GIT_FIELDS.map(([key]) => key);
|
|
32733
32746
|
exports.DEVELOPMENT_PROFILE_KEYS = [...DEVELOPMENT_FIELDS.map(([key]) => key), ...AGENT_GIT_FIELDS.map(([key]) => key)];
|
|
32734
32747
|
function developmentField(key, label, type) {
|
|
32735
32748
|
switch (type) {
|
|
@@ -36152,7 +36165,7 @@ var require_agent_error_details = __commonJS({
|
|
|
36152
36165
|
CLAIMED_BY_OTHER: { holderLabel: string4, expiresAt: string4, holderRef: personRef },
|
|
36153
36166
|
CLAIM_REQUIRED: { issueIds: list2, requiredPurpose: oneOf3(["work"]), providedPurpose: oneOf3(["review"]) },
|
|
36154
36167
|
RENEW_LIMIT: { hardExpiresAt: string4 },
|
|
36155
|
-
NOT_READY: { readySelector: string4 },
|
|
36168
|
+
NOT_READY: { readySelector: string4, reason: oneOf3(["restricted_person", "not_own_agent"]) },
|
|
36156
36169
|
REVISION_CONFLICT: { currentRevision: integer },
|
|
36157
36170
|
STATE_CONFLICT: { currentStateVersion: integer },
|
|
36158
36171
|
TYPED_COMMENT_IMMUTABLE: { kind: string4 },
|
|
@@ -36471,7 +36484,7 @@ var require_dist2 = __commonJS({
|
|
|
36471
36484
|
var import_types11 = __toESM(require_dist(), 1);
|
|
36472
36485
|
import { spawn as spawn9 } from "node:child_process";
|
|
36473
36486
|
import { createHash as createHash9, randomBytes as randomBytes12 } from "node:crypto";
|
|
36474
|
-
import { rm as rm13 } from "node:fs/promises";
|
|
36487
|
+
import { rm as rm13, stat as stat16 } from "node:fs/promises";
|
|
36475
36488
|
import { hostname as osHostname2 } from "node:os";
|
|
36476
36489
|
import { join as join33 } from "node:path";
|
|
36477
36490
|
import { parseArgs } from "node:util";
|
|
@@ -36944,6 +36957,11 @@ var Output = class {
|
|
|
36944
36957
|
if (this.activities.size) this.progress(null);
|
|
36945
36958
|
this.stderr.write(`${this.render(text6, "err")}
|
|
36946
36959
|
`);
|
|
36960
|
+
}
|
|
36961
|
+
/** The keyboard list (tui.ts): CLI-owned cursor control plus rendered lines in one write, so a redraw never flickers. */
|
|
36962
|
+
screen(control, lines) {
|
|
36963
|
+
this.stdout.write(control + lines.map((line) => `${this.render(line, "out")}
|
|
36964
|
+
`).join(""));
|
|
36947
36965
|
}
|
|
36948
36966
|
/** CLI-owned OSC-8 link. The label/URI are neutralized; JSON, pipes and dumb terminals get a plain URL. */
|
|
36949
36967
|
link(label, uri, stream = "out") {
|
|
@@ -37270,20 +37288,32 @@ var EN = {
|
|
|
37270
37288
|
"menu.setupServer": "Server: {server}",
|
|
37271
37289
|
"menu.resume": "Continue {key}",
|
|
37272
37290
|
"menu.ticketDefault": "Ticket key (Enter = {key}):",
|
|
37273
|
-
"menu.fix": "Setup needs attention: {command}
|
|
37274
|
-
"menu.
|
|
37291
|
+
"menu.fix": "Setup needs attention: {command}. Open status and repair.",
|
|
37292
|
+
"menu.recommended": "Recommended",
|
|
37293
|
+
"menu.quit": "Quit",
|
|
37294
|
+
"menu.loading": "Loading …",
|
|
37295
|
+
"menu.yes": "Yes",
|
|
37296
|
+
"menu.no": "No",
|
|
37297
|
+
"menu.yesNo": "(y/N)",
|
|
37298
|
+
"menu.setupComputer": "Set up this computer",
|
|
37299
|
+
"menu.switchCheckout": "Switch checkout",
|
|
37300
|
+
"menu.checkoutTitle": "Which checkout do you want to work in?",
|
|
37301
|
+
"menu.key.move": "↑↓ move",
|
|
37302
|
+
"menu.key.open": "Enter open",
|
|
37303
|
+
"menu.key.confirm": "Enter confirm",
|
|
37304
|
+
"menu.key.back": "Esc back",
|
|
37305
|
+
"menu.key.cancel": "Esc cancel",
|
|
37306
|
+
"menu.key.quit": "q quit",
|
|
37275
37307
|
"menu.connect": "Connect this computer",
|
|
37276
|
-
"menu.bind": "Choose a checkout or set up this computer",
|
|
37277
37308
|
"menu.pick": "My next ticket",
|
|
37278
37309
|
"menu.continue": "Continue a ticket",
|
|
37279
37310
|
"menu.doctor": "Status and repair",
|
|
37280
37311
|
"menu.connections": "Connect ChatGPT / Claude · Settings › Connections",
|
|
37281
37312
|
"menu.help": "All commands",
|
|
37282
|
-
"menu.choose": "Number (Enter
|
|
37283
|
-
"menu.checkout": "Checkout number (0 = setup, Enter cancels):",
|
|
37313
|
+
"menu.choose": "Number (Enter quits):",
|
|
37284
37314
|
"menu.code": "Paste fleek setup <code> from Settings › Connections (Enter cancels):",
|
|
37285
37315
|
"menu.ticket": "Ticket key (Enter cancels):",
|
|
37286
|
-
"menu.repair": "Run {command} to review repair offers?
|
|
37316
|
+
"menu.repair": "Run {command} to review repair offers?",
|
|
37287
37317
|
"read.more": "More details: add --json.",
|
|
37288
37318
|
"read.empty": "No entries.",
|
|
37289
37319
|
"read.items": "Entries",
|
|
@@ -37660,6 +37690,7 @@ var EN = {
|
|
|
37660
37690
|
"orca.rateWait": "Rate limit: waiting {seconds} s, then continuing at the same page.",
|
|
37661
37691
|
"orca.partial": "Partial list after {pages} pages. Narrow it with --project or --mine.",
|
|
37662
37692
|
"orca.listCount": "{count} open tickets · mine first, priority, recently updated",
|
|
37693
|
+
"orca.pickTitle": "{count} tickets · mine first, priority, recently updated",
|
|
37663
37694
|
"orca.pickPage": "Tickets {first}–{last} of {count} · mine first, priority, recently updated",
|
|
37664
37695
|
"orca.pickPages": "n: next page · p: previous page · enter any ticket number",
|
|
37665
37696
|
"errors.proxyProfileAmbiguous": "Several sign-ins are bound to this checkout. Pin one with --profile <key> or FLEEK_PROFILE.",
|
|
@@ -37935,6 +37966,7 @@ var EN = {
|
|
|
37935
37966
|
"init.manualBoundary": "You start the agent yourself: the file selection is only a recommendation, the agent may read more on your machine.",
|
|
37936
37967
|
"init.outputTimeout": "{app}: no output file in time.",
|
|
37937
37968
|
"init.outputInvalid": "{app}: the output file is not valid ({field}).",
|
|
37969
|
+
"init.outputInvalidValue": '{app}: the output file is not valid ({field}: "{value}" is not allowed).',
|
|
37938
37970
|
"init.unusable": "{app}: the analysis contains something that looks like a credential in a required field - nothing sent.",
|
|
37939
37971
|
"init.removed": "{count} value(s) removed: looks like a credential or a forbidden path ({paths}).",
|
|
37940
37972
|
"init.preview": "{app}: {sections} section(s), {components} component(s), {hints} review hint(s), {environments} environment(s), {warnings} hint(s) for the reviewer.",
|
|
@@ -38045,20 +38077,32 @@ var DE = {
|
|
|
38045
38077
|
"menu.setupServer": "Server: {server}",
|
|
38046
38078
|
"menu.resume": "{key} weiterarbeiten",
|
|
38047
38079
|
"menu.ticketDefault": "Ticket-Schlüssel (Enter = {key}):",
|
|
38048
|
-
"menu.fix": "Einrichtung prüfen: {command}
|
|
38049
|
-
"menu.
|
|
38080
|
+
"menu.fix": "Einrichtung prüfen: {command}. Öffne Status und Reparatur.",
|
|
38081
|
+
"menu.recommended": "Empfohlen",
|
|
38082
|
+
"menu.quit": "Beenden",
|
|
38083
|
+
"menu.loading": "Lädt …",
|
|
38084
|
+
"menu.yes": "Ja",
|
|
38085
|
+
"menu.no": "Nein",
|
|
38086
|
+
"menu.yesNo": "(j/N)",
|
|
38087
|
+
"menu.setupComputer": "Rechner einrichten",
|
|
38088
|
+
"menu.switchCheckout": "Checkout wechseln",
|
|
38089
|
+
"menu.checkoutTitle": "In welchem Checkout möchtest du arbeiten?",
|
|
38090
|
+
"menu.key.move": "↑↓ wählen",
|
|
38091
|
+
"menu.key.open": "Enter öffnen",
|
|
38092
|
+
"menu.key.confirm": "Enter bestätigen",
|
|
38093
|
+
"menu.key.back": "Esc zurück",
|
|
38094
|
+
"menu.key.cancel": "Esc abbrechen",
|
|
38095
|
+
"menu.key.quit": "q beenden",
|
|
38050
38096
|
"menu.connect": "Rechner verbinden",
|
|
38051
|
-
"menu.bind": "Checkout wählen oder Rechner einrichten",
|
|
38052
38097
|
"menu.pick": "Mein nächstes Ticket",
|
|
38053
38098
|
"menu.continue": "Ticket fortsetzen",
|
|
38054
38099
|
"menu.doctor": "Status und Reparatur",
|
|
38055
38100
|
"menu.connections": "ChatGPT / Claude verbinden · Einstellungen › Verbindungen",
|
|
38056
38101
|
"menu.help": "Alle Befehle",
|
|
38057
|
-
"menu.choose": "Nummer (Enter
|
|
38058
|
-
"menu.checkout": "Checkout-Nummer (0 = Einrichtung, Enter bricht ab):",
|
|
38102
|
+
"menu.choose": "Nummer (Enter beendet):",
|
|
38059
38103
|
"menu.code": "fleek setup <code> aus Einstellungen › Verbindungen einfügen (Enter bricht ab):",
|
|
38060
38104
|
"menu.ticket": "Ticket-Schlüssel (Enter bricht ab):",
|
|
38061
|
-
"menu.repair": "Mit {command} Reparaturangebote prüfen?
|
|
38105
|
+
"menu.repair": "Mit {command} Reparaturangebote prüfen?",
|
|
38062
38106
|
"read.more": "Weitere Details: --json ergänzen.",
|
|
38063
38107
|
"read.empty": "Keine Einträge.",
|
|
38064
38108
|
"read.items": "Einträge",
|
|
@@ -38308,7 +38352,7 @@ var DE = {
|
|
|
38308
38352
|
" fleek work complete <claim> --outcome done|partial|handed_off --summary <text>",
|
|
38309
38353
|
" fleek work progress <claim> --summary <text>",
|
|
38310
38354
|
"Fragen: fleek ask <ticket> --text <frage> | fleek answer <frage> --text <antwort>",
|
|
38311
|
-
"
|
|
38355
|
+
"Auftragsart: fleek route <ticket> <schlüssel> [--claim <id>] | fleek route <ticket> --default",
|
|
38312
38356
|
"Kontext: fleek context <ticket> | fleek inbox | fleek wait [--cursor <c>] [--seconds <n>]",
|
|
38313
38357
|
"Ereignisse: fleek listen --exec <programm> [args...] [--name <n>] [--timeout <1..3600>] [--concurrency <1|2>] [--quiet-children] [--from-now]",
|
|
38314
38358
|
"MCP: fleek mcp proxy [--profile <schlüssel|workspace>] [--app claude-code|codex|orca] [--label <text>] (stdio-MCP über diese Anmeldung)",
|
|
@@ -38435,6 +38479,7 @@ var DE = {
|
|
|
38435
38479
|
"orca.rateWait": "Anfragelimit: {seconds} s warten, dann auf derselben Seite fortsetzen.",
|
|
38436
38480
|
"orca.partial": "Teilliste nach {pages} Seiten. Mit --project oder --mine eingrenzen.",
|
|
38437
38481
|
"orca.listCount": "{count} offene Tickets · eigene zuerst, Priorität, zuletzt aktualisiert",
|
|
38482
|
+
"orca.pickTitle": "{count} Tickets · eigene zuerst, Priorität, zuletzt aktualisiert",
|
|
38438
38483
|
"orca.pickPage": "Tickets {first}–{last} von {count} · eigene zuerst, Priorität, zuletzt aktualisiert",
|
|
38439
38484
|
"orca.pickPages": "n: nächste Seite · p: vorherige Seite · beliebige Ticket-Nummer eingeben",
|
|
38440
38485
|
"errors.proxyProfileAmbiguous": "Mehrere Anmeldungen sind an dieses Repo gebunden. Leg eine fest mit --profile <schlüssel> oder FLEEK_PROFILE.",
|
|
@@ -38710,6 +38755,7 @@ var DE = {
|
|
|
38710
38755
|
"init.manualBoundary": "Du startest den Agenten selbst: Die Dateiauswahl ist nur eine Empfehlung, der Agent kann auf deinem Rechner mehr lesen.",
|
|
38711
38756
|
"init.outputTimeout": "{app}: keine Ausgabedatei innerhalb der Frist.",
|
|
38712
38757
|
"init.outputInvalid": "{app}: Die Ausgabedatei ist ungültig ({field}).",
|
|
38758
|
+
"init.outputInvalidValue": "{app}: Die Ausgabedatei ist ungültig ({field}: „{value}“ ist nicht erlaubt).",
|
|
38713
38759
|
"init.unusable": "{app}: Die Analyse enthält in einem Pflichtfeld etwas, das wie ein Zugangsschlüssel aussieht - nichts gesendet.",
|
|
38714
38760
|
"init.removed": "{count} Angabe(n) entfernt: sieht aus wie ein Zugangsschlüssel oder ein verbotener Pfad ({paths}).",
|
|
38715
38761
|
"init.preview": "{app}: {sections} Abschnitt(e), {components} Komponente(n), {hints} Prüfhinweis(e), {environments} Umgebung(en), {warnings} Hinweis(e) für die Prüfung.",
|
|
@@ -38807,8 +38853,8 @@ async function processStart(pid) {
|
|
|
38807
38853
|
if (process.platform === "win32") return null;
|
|
38808
38854
|
if (process.platform === "linux") {
|
|
38809
38855
|
try {
|
|
38810
|
-
const
|
|
38811
|
-
const fields =
|
|
38856
|
+
const stat17 = await readFile2(`/proc/${pid}/stat`, "utf8");
|
|
38857
|
+
const fields = stat17.slice(stat17.lastIndexOf(")") + 2).split(" ");
|
|
38812
38858
|
const ticks = Number(fields[19]);
|
|
38813
38859
|
return Number.isSafeInteger(ticks) ? ticks : null;
|
|
38814
38860
|
} catch {
|
|
@@ -49716,7 +49762,7 @@ async function reloadProxyProfile(store, started) {
|
|
|
49716
49762
|
// src/orca.ts
|
|
49717
49763
|
import { execFile as nodeExecFile } from "node:child_process";
|
|
49718
49764
|
import { realpath as realpath4 } from "node:fs/promises";
|
|
49719
|
-
import { posix, win32 } from "node:path";
|
|
49765
|
+
import { posix as posix2, win32 as win322 } from "node:path";
|
|
49720
49766
|
import { setTimeout as sleep4 } from "node:timers/promises";
|
|
49721
49767
|
|
|
49722
49768
|
// src/tools.ts
|
|
@@ -49773,12 +49819,277 @@ var WIRE = {
|
|
|
49773
49819
|
reportServiceHost: "fleek_report_service_host"
|
|
49774
49820
|
};
|
|
49775
49821
|
|
|
49822
|
+
// src/header.ts
|
|
49823
|
+
import { win32, posix } from "node:path";
|
|
49824
|
+
|
|
49825
|
+
// src/uuid.ts
|
|
49826
|
+
var UUID2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
49827
|
+
function isUuid(value) {
|
|
49828
|
+
return UUID2.test(value);
|
|
49829
|
+
}
|
|
49830
|
+
function canonicalId(value) {
|
|
49831
|
+
if (!UUID2.test(value)) throw new Error("INVALID_UUID");
|
|
49832
|
+
return value.toLowerCase();
|
|
49833
|
+
}
|
|
49834
|
+
|
|
49835
|
+
// src/header.ts
|
|
49836
|
+
var LOGO2 = [" ▄██████▀", " ▄█████▀ ", " ██▀ "];
|
|
49837
|
+
var ASCII_LOGO = [" ######/", " #####/ ", " ##/ "];
|
|
49838
|
+
var BRAND = "\x1B[38;2;69;94;255m";
|
|
49839
|
+
function shouldShowHeader(positionals, options, terminal) {
|
|
49840
|
+
if (options.json || options.version || terminal.stream.isTTY !== true) return false;
|
|
49841
|
+
const active = (value) => value !== void 0 && value !== "" && value !== "0" && value !== "false";
|
|
49842
|
+
if (["CI", "CONTINUOUS_INTEGRATION", "GITHUB_ACTIONS", "BUILD_NUMBER", "TF_BUILD"].some((key) => active(terminal.env[key]))) return false;
|
|
49843
|
+
const [command, sub] = positionals;
|
|
49844
|
+
return !command || command === "help" || !!options.help || command === "setup" || command === "doctor" || command === "init" || command === "kit" && ["setup", "doctor", "pull"].includes(sub ?? "") || command === "service" && sub === "setup";
|
|
49845
|
+
}
|
|
49846
|
+
function cells(value) {
|
|
49847
|
+
let width = 0;
|
|
49848
|
+
for (const char of value) {
|
|
49849
|
+
const code = char.codePointAt(0);
|
|
49850
|
+
if (new RegExp("\\p{Mark}", "u").test(char)) continue;
|
|
49851
|
+
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;
|
|
49852
|
+
}
|
|
49853
|
+
return width;
|
|
49854
|
+
}
|
|
49855
|
+
function fit(value, width, ascii) {
|
|
49856
|
+
if (cells(value) <= width) return value;
|
|
49857
|
+
const suffix = ascii ? "..." : "…";
|
|
49858
|
+
if (width <= suffix.length) return suffix.slice(0, Math.max(0, width));
|
|
49859
|
+
let out = "";
|
|
49860
|
+
for (const char of value) {
|
|
49861
|
+
if (cells(out + char) > width - suffix.length) break;
|
|
49862
|
+
out += char;
|
|
49863
|
+
}
|
|
49864
|
+
return out + suffix;
|
|
49865
|
+
}
|
|
49866
|
+
var safe = (value) => neutralizeLine(redact(value));
|
|
49867
|
+
function directory(context, windows, env) {
|
|
49868
|
+
const path = windows ? win32 : posix;
|
|
49869
|
+
const home = context.home ?? userHome(env, windows ? "win32" : process.platform);
|
|
49870
|
+
const relative3 = path.relative(home, context.cwd);
|
|
49871
|
+
const inside = relative3 === "" || relative3 !== ".." && !relative3.startsWith(`..${path.sep}`) && !path.isAbsolute(relative3);
|
|
49872
|
+
return safe(inside ? relative3 ? `~${path.sep}${relative3}` : "~" : context.cwd);
|
|
49873
|
+
}
|
|
49874
|
+
function displayPath(cwd, home, env) {
|
|
49875
|
+
return directory({ version: "", cwd, home }, process.platform === "win32", env);
|
|
49876
|
+
}
|
|
49877
|
+
function headerServer(value) {
|
|
49878
|
+
if (!value) return void 0;
|
|
49879
|
+
try {
|
|
49880
|
+
const url = new URL(value);
|
|
49881
|
+
return ["http:", "https:"].includes(url.protocol) ? url.host : void 0;
|
|
49882
|
+
} catch {
|
|
49883
|
+
return void 0;
|
|
49884
|
+
}
|
|
49885
|
+
}
|
|
49886
|
+
function renderHeader(context, terminal, t) {
|
|
49887
|
+
const windows = (terminal.platform ?? process.platform) === "win32";
|
|
49888
|
+
const ascii = windows || terminal.env.TERM === "dumb";
|
|
49889
|
+
const separator = ascii ? " - " : " · ";
|
|
49890
|
+
const requested = terminal.stream.columns ?? Number(terminal.env.COLUMNS);
|
|
49891
|
+
const columns = Number.isFinite(requested) && requested > 0 ? Math.floor(requested) : 80;
|
|
49892
|
+
const title = t("header.title", { version: safe(context.version) });
|
|
49893
|
+
const cwd = directory(context, windows, terminal.env);
|
|
49894
|
+
const parts = [context.workspace, context.project && !isUuid(context.project) ? context.project : void 0, headerServer(context.server), context.displayName].filter((value) => !!value);
|
|
49895
|
+
const details = parts.length ? parts.map(safe).join(separator) : t("header.noContext");
|
|
49896
|
+
if (columns < 60) return ["", fit([title, cwd].join(separator), columns, ascii)];
|
|
49897
|
+
const logo = ascii ? ASCII_LOGO : LOGO2;
|
|
49898
|
+
const width = Math.max(...logo.map(cells));
|
|
49899
|
+
const color = colorEnabled(terminal.env, terminal.stream);
|
|
49900
|
+
const available2 = columns - width - 6;
|
|
49901
|
+
const tagline = separator + t("header.tagline");
|
|
49902
|
+
const attribution = separator + t("header.attribution");
|
|
49903
|
+
const secondary = cells(title + tagline) <= available2 ? tagline + (cells(title + tagline + attribution) <= available2 ? attribution : "") : "";
|
|
49904
|
+
const text6 = [title, details, cwd];
|
|
49905
|
+
const rows = logo.map((row, index) => {
|
|
49906
|
+
const mark = row.padEnd(width);
|
|
49907
|
+
const label = fit(text6[index], available2, ascii);
|
|
49908
|
+
if (index === 0) {
|
|
49909
|
+
const heading = color ? `\x1B[1m${label}\x1B[22m` : label;
|
|
49910
|
+
const branding = color && secondary ? `\x1B[2m${secondary}\x1B[22m` : secondary;
|
|
49911
|
+
return `${color ? `${BRAND}${mark}\x1B[39m` : mark} ${heading}${branding}`;
|
|
49912
|
+
}
|
|
49913
|
+
const styled = color ? `\x1B[2m${label}\x1B[22m` : label;
|
|
49914
|
+
return `${color ? `${BRAND}${mark}\x1B[39m` : mark} ${styled}`;
|
|
49915
|
+
});
|
|
49916
|
+
const inner = Math.max(...rows.map((row) => cells(stripAnsi(row))));
|
|
49917
|
+
const edge = (value) => color ? `${BRAND}${value}\x1B[39m` : value;
|
|
49918
|
+
const vertical = ascii ? "|" : "│";
|
|
49919
|
+
return [
|
|
49920
|
+
"",
|
|
49921
|
+
edge(`${ascii ? "+" : "╭"}${(ascii ? "-" : "─").repeat(inner + 2)}${ascii ? "+" : "╮"}`),
|
|
49922
|
+
...rows.map((row) => `${edge(vertical)} ${row}${" ".repeat(inner - cells(stripAnsi(row)))} ${edge(vertical)}`),
|
|
49923
|
+
edge(`${ascii ? "+" : "╰"}${(ascii ? "-" : "─").repeat(inner + 2)}${ascii ? "+" : "╯"}`)
|
|
49924
|
+
];
|
|
49925
|
+
}
|
|
49926
|
+
function printHeader(out, context, terminal, t) {
|
|
49927
|
+
for (const line of renderHeader(context, terminal, t)) out.line(line);
|
|
49928
|
+
out.line();
|
|
49929
|
+
out.indentHumanOutput();
|
|
49930
|
+
}
|
|
49931
|
+
|
|
49932
|
+
// src/tui.ts
|
|
49933
|
+
var yesNoList = (question, t) => ({
|
|
49934
|
+
title: [question],
|
|
49935
|
+
items: [{ id: "no", label: t("menu.no") }, { id: "yes", label: t("menu.yes") }],
|
|
49936
|
+
initial: "no",
|
|
49937
|
+
back: true,
|
|
49938
|
+
confirm: true,
|
|
49939
|
+
echo: (item2) => `${question} ${item2.label}`
|
|
49940
|
+
});
|
|
49941
|
+
var isYes = (result) => result.kind === "select" && result.id === "yes";
|
|
49942
|
+
function isKeyInput(stream) {
|
|
49943
|
+
const input = stream;
|
|
49944
|
+
return !!input && input.isTTY === true && typeof input.setRawMode === "function";
|
|
49945
|
+
}
|
|
49946
|
+
var SEQUENCE = /\u001b\[[0-9;]*[A-Za-z~]|\u001bO[A-Za-z]|[\s\S]/g;
|
|
49947
|
+
var NAMED = {
|
|
49948
|
+
"\x1B[A": "up",
|
|
49949
|
+
"\x1BOA": "up",
|
|
49950
|
+
k: "up",
|
|
49951
|
+
"\x1B[B": "down",
|
|
49952
|
+
"\x1BOB": "down",
|
|
49953
|
+
j: "down",
|
|
49954
|
+
"\x1B[H": "home",
|
|
49955
|
+
"\x1BOH": "home",
|
|
49956
|
+
"\x1B[1~": "home",
|
|
49957
|
+
"\x1B[F": "end",
|
|
49958
|
+
"\x1BOF": "end",
|
|
49959
|
+
"\x1B[4~": "end",
|
|
49960
|
+
"\x1B[5~": "pageUp",
|
|
49961
|
+
"\x1B[6~": "pageDown",
|
|
49962
|
+
"\r": "enter",
|
|
49963
|
+
"\n": "enter",
|
|
49964
|
+
"\x1B[C": "enter",
|
|
49965
|
+
"\x1BOC": "enter",
|
|
49966
|
+
"\x1B": "back",
|
|
49967
|
+
"\x1B[D": "back",
|
|
49968
|
+
"\x1BOD": "back",
|
|
49969
|
+
q: "quit",
|
|
49970
|
+
"": "abort",
|
|
49971
|
+
"": "abort"
|
|
49972
|
+
};
|
|
49973
|
+
function parseKeys(chunk) {
|
|
49974
|
+
return (chunk.match(SEQUENCE) ?? []).flatMap((part) => {
|
|
49975
|
+
const named = NAMED[part];
|
|
49976
|
+
if (named) return [named];
|
|
49977
|
+
return /^[1-9]$/.test(part) ? [`digit${Number(part)}`] : [];
|
|
49978
|
+
});
|
|
49979
|
+
}
|
|
49980
|
+
function wrap(text6, width) {
|
|
49981
|
+
const lines = [];
|
|
49982
|
+
let line = "";
|
|
49983
|
+
for (const word of text6.split(" ")) {
|
|
49984
|
+
if (line && cells(`${line} ${word}`) > width) {
|
|
49985
|
+
lines.push(line);
|
|
49986
|
+
line = "";
|
|
49987
|
+
}
|
|
49988
|
+
line = line ? `${line} ${word}` : word;
|
|
49989
|
+
}
|
|
49990
|
+
return [...lines, line].map((entry) => fit(entry, width, false));
|
|
49991
|
+
}
|
|
49992
|
+
function selectList(terminal, options) {
|
|
49993
|
+
const { stdin, stdout, out, t } = terminal;
|
|
49994
|
+
const s = out.style, items = options.items;
|
|
49995
|
+
const pointer = s.unicode ? "›" : ">";
|
|
49996
|
+
let cursor = Math.max(0, items.findIndex((item2) => item2.id === options.initial));
|
|
49997
|
+
let top = 0, drawn = 0;
|
|
49998
|
+
const footer = () => [
|
|
49999
|
+
t("menu.key.move"),
|
|
50000
|
+
t(options.confirm ? "menu.key.confirm" : "menu.key.open"),
|
|
50001
|
+
...options.back ? [t(options.confirm ? "menu.key.cancel" : "menu.key.back")] : [],
|
|
50002
|
+
...options.quit ? [t("menu.key.quit")] : []
|
|
50003
|
+
].join(` ${s.glyph.bullet} `);
|
|
50004
|
+
const view = () => {
|
|
50005
|
+
const width = Math.max(20, (stdout.columns ?? 80) - 3);
|
|
50006
|
+
const title = [
|
|
50007
|
+
...options.context ? [s.dim(fit(neutralizeLine(options.context), width, !s.unicode))] : [],
|
|
50008
|
+
...(options.title ?? []).flatMap((line) => wrap(neutralizeLine(line), width)).map((line) => s.bold(line))
|
|
50009
|
+
];
|
|
50010
|
+
const room = Math.max(3, (stdout.rows ?? 24) - title.length - 5);
|
|
50011
|
+
const size = Math.min(items.length, room);
|
|
50012
|
+
if (cursor < top) top = cursor;
|
|
50013
|
+
if (cursor >= top + size) top = cursor - size + 1;
|
|
50014
|
+
top = Math.min(top, items.length - size);
|
|
50015
|
+
const shown3 = items.slice(top, top + size).map((item2) => ({ item: item2, label: neutralizeLine(item2.label), hint: item2.hint ? neutralizeLine(item2.hint) : "" }));
|
|
50016
|
+
const column = Math.max(...shown3.map(({ label, hint }) => hint ? cells(label) : 0));
|
|
50017
|
+
const rows = shown3.map(({ item: item2, label, hint }) => {
|
|
50018
|
+
const room2 = hint ? width - 2 - cells(hint) - 2 : width - 2;
|
|
50019
|
+
const text6 = fit(label, room2, !s.unicode);
|
|
50020
|
+
const pad = hint ? " ".repeat(Math.max(2, column - cells(text6) + 2)) : "";
|
|
50021
|
+
const chosen = items[cursor] === item2;
|
|
50022
|
+
return `${chosen ? s.cmd(`${pointer} `) : " "}${chosen ? s.bold(s.cmd(text6)) : text6}${pad}${hint ? s.dim(hint) : ""}`;
|
|
50023
|
+
});
|
|
50024
|
+
const position = items.length > size ? `${cursor + 1}/${items.length} ${s.glyph.bullet} ` : "";
|
|
50025
|
+
return [...title, ...title.length ? [""] : [], ...rows, "", s.dim(`${position}${footer()}`)];
|
|
50026
|
+
};
|
|
50027
|
+
const draw = () => {
|
|
50028
|
+
const lines = view();
|
|
50029
|
+
out.screen(`${drawn ? `\x1B[${drawn}A` : ""}\r\x1B[J`, lines);
|
|
50030
|
+
drawn = lines.length;
|
|
50031
|
+
};
|
|
50032
|
+
return new Promise((resolve9) => {
|
|
50033
|
+
const showCursor = () => out.screen("\x1B[?25h", []);
|
|
50034
|
+
const finish2 = (result) => {
|
|
50035
|
+
stdin.off("data", onData);
|
|
50036
|
+
stdin.off("end", onEnd);
|
|
50037
|
+
stdout.off?.("resize", draw);
|
|
50038
|
+
process.off("exit", showCursor);
|
|
50039
|
+
stdin.setRawMode(false);
|
|
50040
|
+
stdin.pause();
|
|
50041
|
+
out.screen(`\x1B[${drawn}A\r\x1B[J\x1B[?25h`, []);
|
|
50042
|
+
if (result.kind === "select") {
|
|
50043
|
+
const item2 = items[cursor];
|
|
50044
|
+
out.line(s.dim(`${pointer} ${neutralizeLine(options.echo ? options.echo(item2) : item2.label)}`));
|
|
50045
|
+
}
|
|
50046
|
+
resolve9(result);
|
|
50047
|
+
};
|
|
50048
|
+
const onEnd = () => finish2({ kind: "abort" });
|
|
50049
|
+
const onData = (chunk) => {
|
|
50050
|
+
for (const key of parseKeys(String(chunk))) {
|
|
50051
|
+
if (key === "abort") return finish2({ kind: "abort" });
|
|
50052
|
+
if (key === "quit" && options.quit) return finish2({ kind: "quit" });
|
|
50053
|
+
if (key === "quit" && options.back) return finish2({ kind: "back" });
|
|
50054
|
+
if (key === "back" && options.back) return finish2({ kind: "back" });
|
|
50055
|
+
if (key === "enter") return finish2({ kind: "select", id: items[cursor].id });
|
|
50056
|
+
if (key === "up") cursor = (cursor - 1 + items.length) % items.length;
|
|
50057
|
+
else if (key === "down") cursor = (cursor + 1) % items.length;
|
|
50058
|
+
else if (key === "home") cursor = 0;
|
|
50059
|
+
else if (key === "end") cursor = items.length - 1;
|
|
50060
|
+
else if (key === "pageUp") cursor = Math.max(0, cursor - 10);
|
|
50061
|
+
else if (key === "pageDown") cursor = Math.min(items.length - 1, cursor + 10);
|
|
50062
|
+
else if (key.startsWith("digit") && !options.confirm) {
|
|
50063
|
+
const index = Number(key.slice(5)) - 1;
|
|
50064
|
+
if (items[index]) {
|
|
50065
|
+
cursor = index;
|
|
50066
|
+
return finish2({ kind: "select", id: items[index].id });
|
|
50067
|
+
}
|
|
50068
|
+
}
|
|
50069
|
+
}
|
|
50070
|
+
draw();
|
|
50071
|
+
};
|
|
50072
|
+
process.once("exit", showCursor);
|
|
50073
|
+
stdin.setRawMode(true);
|
|
50074
|
+
stdin.resume();
|
|
50075
|
+
stdin.on("data", onData);
|
|
50076
|
+
stdin.once("end", onEnd);
|
|
50077
|
+
stdout.on?.("resize", draw);
|
|
50078
|
+
out.screen("\x1B[?25l", []);
|
|
50079
|
+
draw();
|
|
50080
|
+
});
|
|
50081
|
+
}
|
|
50082
|
+
|
|
49776
50083
|
// src/orca.ts
|
|
49777
50084
|
var ORCA_LIMITS = { items: 200, projects: 200, title: 1e3, status: 120, id: 200 };
|
|
49778
50085
|
var KEY = /^[A-Z0-9]{2,10}-[1-9][0-9]*$/;
|
|
49779
|
-
var
|
|
50086
|
+
var UUID3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
49780
50087
|
var CLOSED = /* @__PURE__ */ new Set(["completed", "cancelled", "canceled"]);
|
|
49781
|
-
var terminalConfirm = (deps) => async (question) =>
|
|
50088
|
+
var terminalConfirm = (deps) => async (question) => {
|
|
50089
|
+
if (!deps.isTTY || !deps.ask) return null;
|
|
50090
|
+
if (deps.select) return isYes(await deps.select(yesNoList(question, deps.t)));
|
|
50091
|
+
return /^(y|yes|j|ja)$/i.test((await deps.ask(`${question} (y/N)`)).trim());
|
|
50092
|
+
};
|
|
49782
50093
|
var notBound = () => new CliError("errors.orcaNotBound", EXIT.failed, {}, "NOT_BOUND");
|
|
49783
50094
|
var usage = () => new CliError("errors.usage", EXIT.usage, {}, "USAGE");
|
|
49784
50095
|
var bounded = (value, max) => String(value ?? "").slice(0, max);
|
|
@@ -49845,7 +50156,7 @@ async function readTool(client, tool, args, read2) {
|
|
|
49845
50156
|
}
|
|
49846
50157
|
async function claimableIds(client, teamId, read2) {
|
|
49847
50158
|
const candidates = await pages(client, WIRE.findWork, { ...teamId ? { teamId } : {} }, void 0, read2);
|
|
49848
|
-
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) =>
|
|
50159
|
+
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)));
|
|
49849
50160
|
}
|
|
49850
50161
|
async function pages(client, tool, args, max = Number.POSITIVE_INFINITY, read2) {
|
|
49851
50162
|
await available(client, tool);
|
|
@@ -49886,7 +50197,7 @@ function sortIssues(issues, mine) {
|
|
|
49886
50197
|
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 }));
|
|
49887
50198
|
}
|
|
49888
50199
|
async function teams(client, read2) {
|
|
49889
|
-
return (await pages(client, "fleek_list_teams", {}, ORCA_LIMITS.projects, read2)).filter((team) => typeof team.id === "string" &&
|
|
50200
|
+
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) }));
|
|
49890
50201
|
}
|
|
49891
50202
|
async function statesOf(client, teamIds, read2) {
|
|
49892
50203
|
const states = /* @__PURE__ */ new Map();
|
|
@@ -49898,9 +50209,9 @@ async function statesOf(client, teamIds, read2) {
|
|
|
49898
50209
|
return states;
|
|
49899
50210
|
}
|
|
49900
50211
|
function item(profile, issue, teamsById, states) {
|
|
49901
|
-
const id = typeof issue.id === "string" &&
|
|
50212
|
+
const id = typeof issue.id === "string" && UUID3.test(issue.id) ? issue.id.toLowerCase() : null;
|
|
49902
50213
|
const key = typeof issue.identifier === "string" && KEY.test(issue.identifier) ? issue.identifier : null;
|
|
49903
|
-
const teamId = typeof issue.teamId === "string" &&
|
|
50214
|
+
const teamId = typeof issue.teamId === "string" && UUID3.test(issue.teamId) ? issue.teamId.toLowerCase() : null;
|
|
49904
50215
|
if (!id || !key || !teamId) return null;
|
|
49905
50216
|
const status = typeof issue.stateId === "string" ? states.get(issue.stateId.toLowerCase())?.name ?? "" : "";
|
|
49906
50217
|
return { id, key, title: bounded(issue.title, ORCA_LIMITS.title), status, url: ticketUrl(profile, teamsById.get(teamId)?.key ?? null, key), projectId: teamId };
|
|
@@ -49908,14 +50219,14 @@ function item(profile, issue, teamsById, states) {
|
|
|
49908
50219
|
function projectOf(values, found, list2) {
|
|
49909
50220
|
if (values.project === void 0) return found.projectId;
|
|
49910
50221
|
const value = values.project.trim();
|
|
49911
|
-
const match =
|
|
50222
|
+
const match = UUID3.test(value) ? list2.find((team) => team.id === value.toLowerCase()) : list2.find((team) => team.key.toUpperCase() === value.toUpperCase());
|
|
49912
50223
|
if (!match) throw new CliError("errors.orcaProjectUnknown", EXIT.usage, {}, "NOT_FOUND");
|
|
49913
50224
|
return match.id;
|
|
49914
50225
|
}
|
|
49915
50226
|
async function myUserId(client, read2) {
|
|
49916
50227
|
const who = (await readTool(client, WIRE.whoami, {}, read2)).structured;
|
|
49917
50228
|
const id = who.principal?.userId;
|
|
49918
|
-
if (typeof id !== "string" || !
|
|
50229
|
+
if (typeof id !== "string" || !UUID3.test(id)) throw new CliError("errors.metadata", EXIT.failed, { reason: "context" }, "METADATA_INVALID");
|
|
49919
50230
|
return id.toLowerCase();
|
|
49920
50231
|
}
|
|
49921
50232
|
async function orcaContext(deps, values = {}) {
|
|
@@ -50013,7 +50324,7 @@ var defaultExec = (program, args, options) => new Promise((resolve9) => nodeExec
|
|
|
50013
50324
|
(error, stdout, stderr) => resolve9({ code: error ? typeof error.code === "number" ? error.code : 1 : 0, stdout: String(stdout), stderr: String(stderr) })
|
|
50014
50325
|
));
|
|
50015
50326
|
async function orcaProgram(deps, runtime = { platform: process.platform }) {
|
|
50016
|
-
const paths = runtime.platform === "win32" ?
|
|
50327
|
+
const paths = runtime.platform === "win32" ? win322 : posix2;
|
|
50017
50328
|
const custom = deps.env.ORCA_CLI_COMMAND || void 0;
|
|
50018
50329
|
const found = custom ?? (runtime.platform === "linux" ? await deps.which("orca-ide") : null) ?? await deps.which("orca");
|
|
50019
50330
|
if (!found || !paths.isAbsolute(found) || paths.resolve(found) === "/usr/bin/orca" || await (runtime.realpath ?? realpath4)(found).catch(() => found) === "/usr/bin/orca") {
|
|
@@ -50053,6 +50364,11 @@ async function orcaPick(deps, values, start2) {
|
|
|
50053
50364
|
deps.out.line(deps.out.style.note(deps.t("orca.none")));
|
|
50054
50365
|
return EXIT.ok;
|
|
50055
50366
|
}
|
|
50367
|
+
if (deps.select) {
|
|
50368
|
+
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)]), "");
|
|
50369
|
+
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 });
|
|
50370
|
+
return choice.kind === "select" ? start2(choice.id) : EXIT.ok;
|
|
50371
|
+
}
|
|
50056
50372
|
let offset = 0;
|
|
50057
50373
|
while (true) {
|
|
50058
50374
|
const end = Math.min(offset + 50, items.length);
|
|
@@ -50158,7 +50474,7 @@ async function liveFacts(client, task) {
|
|
|
50158
50474
|
const claims = (Array.isArray(work2.claims) ? work2.claims : []).filter(object3).map((claim) => ({
|
|
50159
50475
|
purpose: string3(claim.purpose),
|
|
50160
50476
|
isMine: claim.isMine === true,
|
|
50161
|
-
claimId: typeof claim.claimId === "string" &&
|
|
50477
|
+
claimId: typeof claim.claimId === "string" && UUID3.test(claim.claimId) ? claim.claimId.toLowerCase() : null,
|
|
50162
50478
|
holder: object3(claim.holder) ? string3(claim.holder.text) : "",
|
|
50163
50479
|
expiresAt: string3(claim.expiresAt)
|
|
50164
50480
|
}));
|
|
@@ -50264,7 +50580,7 @@ var foreignClaim = (key, holder, expiresAt) => new CliError(
|
|
|
50264
50580
|
async function takeClaim(deps, client, task, purpose, runLabel) {
|
|
50265
50581
|
try {
|
|
50266
50582
|
const claim = (await mutate(client, WIRE.claim, { issueId: task.id, purpose, runLabel: runLabel.slice(0, 120) }, { backoffMs: deps.backoffMs })).result;
|
|
50267
|
-
return typeof claim.claimId === "string" &&
|
|
50583
|
+
return typeof claim.claimId === "string" && UUID3.test(claim.claimId) ? claim.claimId.toLowerCase() : null;
|
|
50268
50584
|
} catch (error) {
|
|
50269
50585
|
if (error instanceof ToolError && error.code === "ALREADY_CLAIMED") {
|
|
50270
50586
|
const details = object3(error.details) ? error.details : {};
|
|
@@ -51751,7 +52067,7 @@ var USER_SKILL_MARKER = "<!-- Generated by scripts/agent-guidance/generate.mjs f
|
|
|
51751
52067
|
var USER_SKILLS = [
|
|
51752
52068
|
{
|
|
51753
52069
|
"name": "fleek-orca-coordinator",
|
|
51754
|
-
"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"
|
|
52070
|
+
"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"
|
|
51755
52071
|
}
|
|
51756
52072
|
];
|
|
51757
52073
|
|
|
@@ -51981,8 +52297,9 @@ function initAgentArgs(prompt) {
|
|
|
51981
52297
|
JSON.stringify({ disableAllHooks: true })
|
|
51982
52298
|
];
|
|
51983
52299
|
}
|
|
51984
|
-
function initAgentEnv(env) {
|
|
51985
|
-
const
|
|
52300
|
+
function initAgentEnv(env, platform = process.platform) {
|
|
52301
|
+
const path = platform === "darwin" ? [dirname9(process.execPath), "/usr/bin"] : [dirname9(process.execPath)];
|
|
52302
|
+
const result = { PATH: path.join(delimiter2) };
|
|
51986
52303
|
for (const key of [
|
|
51987
52304
|
"HOME",
|
|
51988
52305
|
"USER",
|
|
@@ -54265,113 +54582,6 @@ var Session = class {
|
|
|
54265
54582
|
}
|
|
54266
54583
|
};
|
|
54267
54584
|
|
|
54268
|
-
// src/header.ts
|
|
54269
|
-
import { win32 as win322, posix as posix2 } from "node:path";
|
|
54270
|
-
|
|
54271
|
-
// src/uuid.ts
|
|
54272
|
-
var UUID3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
54273
|
-
function isUuid(value) {
|
|
54274
|
-
return UUID3.test(value);
|
|
54275
|
-
}
|
|
54276
|
-
function canonicalId(value) {
|
|
54277
|
-
if (!UUID3.test(value)) throw new Error("INVALID_UUID");
|
|
54278
|
-
return value.toLowerCase();
|
|
54279
|
-
}
|
|
54280
|
-
|
|
54281
|
-
// src/header.ts
|
|
54282
|
-
var LOGO2 = [" ▄██████▀", " ▄█████▀ ", " ██▀ "];
|
|
54283
|
-
var ASCII_LOGO = [" ######/", " #####/ ", " ##/ "];
|
|
54284
|
-
var BRAND = "\x1B[38;2;69;94;255m";
|
|
54285
|
-
function shouldShowHeader(positionals, options, terminal) {
|
|
54286
|
-
if (options.json || options.version || terminal.stream.isTTY !== true) return false;
|
|
54287
|
-
const active = (value) => value !== void 0 && value !== "" && value !== "0" && value !== "false";
|
|
54288
|
-
if (["CI", "CONTINUOUS_INTEGRATION", "GITHUB_ACTIONS", "BUILD_NUMBER", "TF_BUILD"].some((key) => active(terminal.env[key]))) return false;
|
|
54289
|
-
const [command, sub] = positionals;
|
|
54290
|
-
return !command || command === "help" || !!options.help || command === "setup" || command === "doctor" || command === "init" || command === "kit" && ["setup", "doctor", "pull"].includes(sub ?? "") || command === "service" && sub === "setup";
|
|
54291
|
-
}
|
|
54292
|
-
function cells(value) {
|
|
54293
|
-
let width = 0;
|
|
54294
|
-
for (const char of value) {
|
|
54295
|
-
const code = char.codePointAt(0);
|
|
54296
|
-
if (new RegExp("\\p{Mark}", "u").test(char)) continue;
|
|
54297
|
-
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;
|
|
54298
|
-
}
|
|
54299
|
-
return width;
|
|
54300
|
-
}
|
|
54301
|
-
function fit(value, width, ascii) {
|
|
54302
|
-
if (cells(value) <= width) return value;
|
|
54303
|
-
const suffix = ascii ? "..." : "…";
|
|
54304
|
-
if (width <= suffix.length) return suffix.slice(0, Math.max(0, width));
|
|
54305
|
-
let out = "";
|
|
54306
|
-
for (const char of value) {
|
|
54307
|
-
if (cells(out + char) > width - suffix.length) break;
|
|
54308
|
-
out += char;
|
|
54309
|
-
}
|
|
54310
|
-
return out + suffix;
|
|
54311
|
-
}
|
|
54312
|
-
var safe = (value) => neutralizeLine(redact(value));
|
|
54313
|
-
function directory(context, windows, env) {
|
|
54314
|
-
const path = windows ? win322 : posix2;
|
|
54315
|
-
const home = context.home ?? userHome(env, windows ? "win32" : process.platform);
|
|
54316
|
-
const relative3 = path.relative(home, context.cwd);
|
|
54317
|
-
const inside = relative3 === "" || relative3 !== ".." && !relative3.startsWith(`..${path.sep}`) && !path.isAbsolute(relative3);
|
|
54318
|
-
return safe(inside ? relative3 ? `~${path.sep}${relative3}` : "~" : context.cwd);
|
|
54319
|
-
}
|
|
54320
|
-
function headerServer(value) {
|
|
54321
|
-
if (!value) return void 0;
|
|
54322
|
-
try {
|
|
54323
|
-
const url = new URL(value);
|
|
54324
|
-
return ["http:", "https:"].includes(url.protocol) ? url.host : void 0;
|
|
54325
|
-
} catch {
|
|
54326
|
-
return void 0;
|
|
54327
|
-
}
|
|
54328
|
-
}
|
|
54329
|
-
function renderHeader(context, terminal, t) {
|
|
54330
|
-
const windows = (terminal.platform ?? process.platform) === "win32";
|
|
54331
|
-
const ascii = windows || terminal.env.TERM === "dumb";
|
|
54332
|
-
const separator = ascii ? " - " : " · ";
|
|
54333
|
-
const requested = terminal.stream.columns ?? Number(terminal.env.COLUMNS);
|
|
54334
|
-
const columns = Number.isFinite(requested) && requested > 0 ? Math.floor(requested) : 80;
|
|
54335
|
-
const title = t("header.title", { version: safe(context.version) });
|
|
54336
|
-
const cwd = directory(context, windows, terminal.env);
|
|
54337
|
-
const parts = [context.workspace, context.project && !isUuid(context.project) ? context.project : void 0, headerServer(context.server), context.displayName].filter((value) => !!value);
|
|
54338
|
-
const details = parts.length ? parts.map(safe).join(separator) : t("header.noContext");
|
|
54339
|
-
if (columns < 60) return ["", fit([title, cwd].join(separator), columns, ascii)];
|
|
54340
|
-
const logo = ascii ? ASCII_LOGO : LOGO2;
|
|
54341
|
-
const width = Math.max(...logo.map(cells));
|
|
54342
|
-
const color = colorEnabled(terminal.env, terminal.stream);
|
|
54343
|
-
const available2 = columns - width - 6;
|
|
54344
|
-
const tagline = separator + t("header.tagline");
|
|
54345
|
-
const attribution = separator + t("header.attribution");
|
|
54346
|
-
const secondary = cells(title + tagline) <= available2 ? tagline + (cells(title + tagline + attribution) <= available2 ? attribution : "") : "";
|
|
54347
|
-
const text6 = [title, details, cwd];
|
|
54348
|
-
const rows = logo.map((row, index) => {
|
|
54349
|
-
const mark = row.padEnd(width);
|
|
54350
|
-
const label = fit(text6[index], available2, ascii);
|
|
54351
|
-
if (index === 0) {
|
|
54352
|
-
const heading = color ? `\x1B[1m${label}\x1B[22m` : label;
|
|
54353
|
-
const branding = color && secondary ? `\x1B[2m${secondary}\x1B[22m` : secondary;
|
|
54354
|
-
return `${color ? `${BRAND}${mark}\x1B[39m` : mark} ${heading}${branding}`;
|
|
54355
|
-
}
|
|
54356
|
-
const styled = color ? `\x1B[2m${label}\x1B[22m` : label;
|
|
54357
|
-
return `${color ? `${BRAND}${mark}\x1B[39m` : mark} ${styled}`;
|
|
54358
|
-
});
|
|
54359
|
-
const inner = Math.max(...rows.map((row) => cells(stripAnsi(row))));
|
|
54360
|
-
const edge = (value) => color ? `${BRAND}${value}\x1B[39m` : value;
|
|
54361
|
-
const vertical = ascii ? "|" : "│";
|
|
54362
|
-
return [
|
|
54363
|
-
"",
|
|
54364
|
-
edge(`${ascii ? "+" : "╭"}${(ascii ? "-" : "─").repeat(inner + 2)}${ascii ? "+" : "╮"}`),
|
|
54365
|
-
...rows.map((row) => `${edge(vertical)} ${row}${" ".repeat(inner - cells(stripAnsi(row)))} ${edge(vertical)}`),
|
|
54366
|
-
edge(`${ascii ? "+" : "╰"}${(ascii ? "-" : "─").repeat(inner + 2)}${ascii ? "+" : "╯"}`)
|
|
54367
|
-
];
|
|
54368
|
-
}
|
|
54369
|
-
function printHeader(out, context, terminal, t) {
|
|
54370
|
-
for (const line of renderHeader(context, terminal, t)) out.line(line);
|
|
54371
|
-
out.line();
|
|
54372
|
-
out.indentHumanOutput();
|
|
54373
|
-
}
|
|
54374
|
-
|
|
54375
54585
|
// src/project-reference.ts
|
|
54376
54586
|
async function visibleProject(client, ref) {
|
|
54377
54587
|
let cursor;
|
|
@@ -57296,9 +57506,43 @@ function instructions2(ctx, app, facts) {
|
|
|
57296
57506
|
}, null, 2),
|
|
57297
57507
|
"```",
|
|
57298
57508
|
"",
|
|
57509
|
+
...allowedValueLines(de),
|
|
57299
57510
|
de ? `Grenzen: Abschnitte ≤ ${import_validation3.PROJECT_INIT_LIMITS.section} Zeichen, Hinweise ≤ ${import_validation3.PROJECT_INIT_LIMITS.reviewHints}, Datei ≤ 64 KiB. Einfacher Text mit Absätzen und Spiegelstrichen.` : `Bounds: sections <= ${import_validation3.PROJECT_INIT_LIMITS.section} characters, hints <= ${import_validation3.PROJECT_INIT_LIMITS.reviewHints}, file <= 64 KiB. Plain text with paragraphs and bullets.`
|
|
57300
57511
|
].join("\n");
|
|
57301
57512
|
}
|
|
57513
|
+
var INIT_AGENT_ENUM_FIELDS = [
|
|
57514
|
+
["cms.items[].kind", import_validation3.PROJECT_INIT_CMS_ITEM_KINDS],
|
|
57515
|
+
["integrations[].kind", import_validation3.PROJECT_INIT_INTEGRATION_KINDS],
|
|
57516
|
+
["integrations[].direction", import_validation3.PROJECT_INIT_DIRECTIONS],
|
|
57517
|
+
["environments[].label", import_validation3.PROJECT_INIT_ENVIRONMENTS],
|
|
57518
|
+
["reviewHints[].topic", import_validation3.PROJECT_INIT_HINT_TOPICS],
|
|
57519
|
+
["statementChecks[].result", import_validation3.PROJECT_INIT_STATEMENT_RESULTS]
|
|
57520
|
+
];
|
|
57521
|
+
function allowedValueLines(de) {
|
|
57522
|
+
return [
|
|
57523
|
+
de ? "## Erlaubte Werte" : "## Allowed values",
|
|
57524
|
+
de ? "- Diese Felder nehmen genau einen der genannten Werte; jeder andere Wert macht die ganze Ausgabe ungültig. Passt keiner, nimm `other`, wo es ihn gibt." : "- These fields take exactly one of the listed values; any other value invalidates the whole output. If none fits, use `other` where it exists.",
|
|
57525
|
+
...INIT_AGENT_ENUM_FIELDS.map(([field, values]) => `- \`${field}\`: ${values.map((value) => `\`${value}\``).join(", ")}`),
|
|
57526
|
+
""
|
|
57527
|
+
];
|
|
57528
|
+
}
|
|
57529
|
+
function rejectedEnumValue(root, issue) {
|
|
57530
|
+
if (!issue || issue.reason !== "invalid_enum_value") return null;
|
|
57531
|
+
let current2 = root;
|
|
57532
|
+
for (const [, index, key] of issue.path.matchAll(/\[(\d+)\]|([^.[\]]+)/g)) {
|
|
57533
|
+
if (current2 === null || typeof current2 !== "object") return null;
|
|
57534
|
+
const step = index !== void 0 ? Number(index) : key;
|
|
57535
|
+
if (!Object.prototype.hasOwnProperty.call(current2, step)) return null;
|
|
57536
|
+
current2 = current2[step];
|
|
57537
|
+
}
|
|
57538
|
+
if (typeof current2 !== "string" || current2.length === 0 || current2.length > 40 || !/^[\p{L}\p{N} _.\-/]+$/u.test(current2)) return null;
|
|
57539
|
+
return (0, import_validation3.detectSecretShape)(current2) ? null : current2;
|
|
57540
|
+
}
|
|
57541
|
+
function outputInvalidLine(ctx, app, root, issue) {
|
|
57542
|
+
const field = issue?.path || "-";
|
|
57543
|
+
const value = rejectedEnumValue(root, issue);
|
|
57544
|
+
return value === null ? ctx.t("init.outputInvalid", { app, field }) : ctx.t("init.outputInvalidValue", { app, field, value });
|
|
57545
|
+
}
|
|
57302
57546
|
function projectFactLines(de, facts) {
|
|
57303
57547
|
const matched = projectFactsForStack(facts.stack.map((item2) => item2.product));
|
|
57304
57548
|
if (!matched.length) return [];
|
|
@@ -57779,7 +58023,7 @@ async function runApplication(ctx, client, values, checkout, context, app, appli
|
|
|
57779
58023
|
const agentOutput = raw === void 0 ? null : (0, import_validation3.parseProjectInitAgentOutput)(raw);
|
|
57780
58024
|
if (!agentOutput?.ok) {
|
|
57781
58025
|
emit(ctx, { event: "error", app: app.key, code: "output_invalid" });
|
|
57782
|
-
if (!ctx.json) ctx.out.error(ctx.out.style.fail(ctx
|
|
58026
|
+
if (!ctx.json) ctx.out.error(ctx.out.style.fail(outputInvalidLine(ctx, app.key, raw, agentOutput && !agentOutput.ok ? agentOutput.issues[0] : void 0)));
|
|
57783
58027
|
return "failed";
|
|
57784
58028
|
}
|
|
57785
58029
|
const composed = (0, import_validation3.composeProjectInitSummary)({
|
|
@@ -57791,7 +58035,7 @@ async function runApplication(ctx, client, values, checkout, context, app, appli
|
|
|
57791
58035
|
const parsed = (0, import_validation3.parseProjectInitSummary)(composed);
|
|
57792
58036
|
if (!parsed.ok) {
|
|
57793
58037
|
emit(ctx, { event: "error", app: app.key, code: "output_invalid" });
|
|
57794
|
-
if (!ctx.json) ctx.out.error(ctx.out.style.fail(ctx
|
|
58038
|
+
if (!ctx.json) ctx.out.error(ctx.out.style.fail(outputInvalidLine(ctx, app.key, composed, parsed.issues[0])));
|
|
57795
58039
|
return "failed";
|
|
57796
58040
|
}
|
|
57797
58041
|
const findings = (0, import_validation3.scanProjectInit)(parsed.value);
|
|
@@ -59288,6 +59532,20 @@ async function guidedMenu(d) {
|
|
|
59288
59532
|
out.line(`$ fleek ${args[0] === "setup" && args[1] && !args[1].startsWith("--") ? "setup <code>" : args.map(neutralizeLine).join(" ")}`);
|
|
59289
59533
|
return d.run(args, cwd2);
|
|
59290
59534
|
};
|
|
59535
|
+
const choose = async (options) => {
|
|
59536
|
+
if (d.select) return d.select(options);
|
|
59537
|
+
for (const line of [...options.context ? [options.context] : [], ...options.title ?? []]) out.line(line);
|
|
59538
|
+
for (const [i, item2] of options.items.entries()) out.line(`${i + 1} ${item2.label}${item2.hint ? ` · ${item2.hint}` : ""}`);
|
|
59539
|
+
const answer2 = (await d.ask(t("menu.choose"))).trim();
|
|
59540
|
+
if (!answer2) return { kind: "back" };
|
|
59541
|
+
const chosen = /^[1-9][0-9]*$/.test(answer2) ? options.items[Number(answer2) - 1] : void 0;
|
|
59542
|
+
if (!chosen) throw new CliError("errors.usage", EXIT.usage, {}, "USAGE");
|
|
59543
|
+
return { kind: "select", id: chosen.id };
|
|
59544
|
+
};
|
|
59545
|
+
const confirm2 = async (question) => {
|
|
59546
|
+
if (!d.select) return /^(y|yes|j|ja)$/i.test((await d.ask(`${question} ${t("menu.yesNo")}`)).trim());
|
|
59547
|
+
return isYes(await d.select(yesNoList(question, t)));
|
|
59548
|
+
};
|
|
59291
59549
|
const connect = async (setup) => {
|
|
59292
59550
|
await d.connect();
|
|
59293
59551
|
if (!setup) return EXIT.ok;
|
|
@@ -59311,53 +59569,121 @@ async function guidedMenu(d) {
|
|
|
59311
59569
|
}
|
|
59312
59570
|
return run2(["setup", code, ...language ? ["--language", language] : []]);
|
|
59313
59571
|
};
|
|
59314
|
-
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") }));
|
|
59315
|
-
if (d.stateError) out.line(t("menu.stateUnreadable"));
|
|
59316
|
-
if (!d.signedIn) {
|
|
59317
|
-
out.line(`1 ${t("menu.connect")}`);
|
|
59318
|
-
out.line(`2 ${t("menu.help")}`);
|
|
59319
|
-
const choice2 = (await d.ask(t("menu.choose"))).trim();
|
|
59320
|
-
if (!choice2) return EXIT.ok;
|
|
59321
|
-
if (choice2 === "1") return connect(true);
|
|
59322
|
-
if (choice2 === "2") return run2(["help"]);
|
|
59323
|
-
throw new CliError("errors.usage", EXIT.usage, {}, "USAGE");
|
|
59324
|
-
}
|
|
59325
59572
|
let cwd;
|
|
59326
|
-
|
|
59327
|
-
|
|
59328
|
-
|
|
59329
|
-
|
|
59330
|
-
|
|
59331
|
-
|
|
59332
|
-
|
|
59333
|
-
|
|
59334
|
-
|
|
59335
|
-
|
|
59336
|
-
|
|
59337
|
-
|
|
59338
|
-
|
|
59339
|
-
|
|
59340
|
-
|
|
59573
|
+
let state;
|
|
59574
|
+
let cursor;
|
|
59575
|
+
while (true) {
|
|
59576
|
+
if (!state) {
|
|
59577
|
+
out.progress(t("menu.loading"));
|
|
59578
|
+
try {
|
|
59579
|
+
state = await d.state(cwd);
|
|
59580
|
+
} catch {
|
|
59581
|
+
state = { signedIn: false, bound: false, stateError: true, checkouts: [] };
|
|
59582
|
+
}
|
|
59583
|
+
out.progress(null);
|
|
59584
|
+
if (cwd && !state.bound && !state.stateError) {
|
|
59585
|
+
cwd = void 0;
|
|
59586
|
+
continue;
|
|
59587
|
+
}
|
|
59588
|
+
}
|
|
59589
|
+
const current2 = state;
|
|
59590
|
+
const recommended = (id2, wanted2) => id2 === wanted2 ? { hint: t("menu.recommended") } : {};
|
|
59591
|
+
const chooser2 = current2.signedIn && !current2.bound && !current2.stateError;
|
|
59592
|
+
const canSwitch = !chooser2 && !!cwd;
|
|
59593
|
+
const wanted = !current2.signedIn ? "connect" : current2.resume ? "resume" : current2.stateError ? "doctor" : "pick";
|
|
59594
|
+
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 ? [
|
|
59595
|
+
...current2.checkouts.map((checkout, i) => ({ id: `checkout:${i}`, label: checkout.label ?? checkout.path, ...checkout.project ? { hint: checkout.project } : {} })),
|
|
59596
|
+
{ id: "connect", label: t("menu.setupComputer") },
|
|
59597
|
+
{ id: "help", label: t("menu.help") },
|
|
59598
|
+
{ id: "quit", label: t("menu.quit") }
|
|
59599
|
+
] : [
|
|
59600
|
+
...current2.resume ? [{ id: "resume", label: t("menu.resume", { key: current2.resume }), ...recommended("resume", wanted) }] : [],
|
|
59601
|
+
{ id: "pick", label: t("menu.pick"), ...recommended("pick", wanted) },
|
|
59602
|
+
{ id: "continue", label: t("menu.continue") },
|
|
59603
|
+
{ id: "doctor", label: t("menu.doctor"), ...recommended("doctor", wanted) },
|
|
59604
|
+
{ id: "connections", label: t("menu.connections") },
|
|
59605
|
+
...canSwitch ? [{ id: "switch", label: t("menu.switchCheckout") }] : [],
|
|
59606
|
+
{ id: "help", label: t("menu.help") },
|
|
59607
|
+
{ id: "quit", label: t("menu.quit") }
|
|
59608
|
+
];
|
|
59609
|
+
const title = [
|
|
59610
|
+
...chooser2 ? [t("menu.checkoutTitle")] : [],
|
|
59611
|
+
...current2.stateError && current2.signedIn ? [t("menu.stateUnreadable")] : [],
|
|
59612
|
+
...current2.repair && current2.signedIn && !chooser2 ? [t("menu.fix", { command: `fleek ${repair.join(" ")}` })] : []
|
|
59613
|
+
];
|
|
59614
|
+
let choice;
|
|
59615
|
+
try {
|
|
59616
|
+
choice = await choose({ ...current2.context ? { context: current2.context } : {}, title, items, initial: cursor && items.some((item2) => item2.id === cursor) ? cursor : wanted, quit: true, back: canSwitch });
|
|
59617
|
+
} catch (error) {
|
|
59618
|
+
d.report(error);
|
|
59619
|
+
out.line();
|
|
59620
|
+
continue;
|
|
59621
|
+
}
|
|
59622
|
+
if (choice.kind !== "select") {
|
|
59623
|
+
if (choice.kind === "back" && canSwitch) {
|
|
59624
|
+
cwd = void 0;
|
|
59625
|
+
state = void 0;
|
|
59626
|
+
cursor = void 0;
|
|
59627
|
+
continue;
|
|
59628
|
+
}
|
|
59341
59629
|
return EXIT.ok;
|
|
59342
|
-
case "1":
|
|
59343
|
-
return run2(["start", "--mine"], cwd);
|
|
59344
|
-
case "2": {
|
|
59345
|
-
const key = (await d.ask(d.resume ? t("menu.ticketDefault", { key: d.resume }) : t("menu.ticket"))).trim().toUpperCase() || d.resume;
|
|
59346
|
-
if (!key) return EXIT.ok;
|
|
59347
|
-
if (!/^[A-Z0-9]{2,10}-[1-9][0-9]*$/.test(key)) throw new CliError("errors.usage", EXIT.usage, {}, "USAGE");
|
|
59348
|
-
return run2(["start", key], cwd);
|
|
59349
|
-
}
|
|
59350
|
-
case "3": {
|
|
59351
|
-
const code = await run2(["doctor"], cwd);
|
|
59352
|
-
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);
|
|
59353
|
-
return code;
|
|
59354
59630
|
}
|
|
59355
|
-
|
|
59356
|
-
|
|
59357
|
-
|
|
59358
|
-
|
|
59359
|
-
|
|
59360
|
-
|
|
59631
|
+
const id = choice.id;
|
|
59632
|
+
if (id === "quit") return EXIT.ok;
|
|
59633
|
+
cursor = id;
|
|
59634
|
+
if (id === "switch") {
|
|
59635
|
+
cwd = void 0;
|
|
59636
|
+
state = void 0;
|
|
59637
|
+
cursor = void 0;
|
|
59638
|
+
continue;
|
|
59639
|
+
}
|
|
59640
|
+
if (id.startsWith("checkout:")) {
|
|
59641
|
+
cwd = current2.checkouts[Number(id.slice(9))]?.path;
|
|
59642
|
+
state = void 0;
|
|
59643
|
+
cursor = void 0;
|
|
59644
|
+
continue;
|
|
59645
|
+
}
|
|
59646
|
+
let refresh = true, code = EXIT.ok;
|
|
59647
|
+
try {
|
|
59648
|
+
switch (id) {
|
|
59649
|
+
case "connect":
|
|
59650
|
+
code = await connect(true);
|
|
59651
|
+
break;
|
|
59652
|
+
case "resume":
|
|
59653
|
+
code = await run2(["start", current2.resume], cwd);
|
|
59654
|
+
break;
|
|
59655
|
+
case "pick":
|
|
59656
|
+
code = await run2(["start", "--mine"], cwd);
|
|
59657
|
+
break;
|
|
59658
|
+
case "continue": {
|
|
59659
|
+
const key = (await d.ask(current2.resume ? t("menu.ticketDefault", { key: current2.resume }) : t("menu.ticket"))).trim().toUpperCase() || current2.resume;
|
|
59660
|
+
if (!key) {
|
|
59661
|
+
refresh = false;
|
|
59662
|
+
break;
|
|
59663
|
+
}
|
|
59664
|
+
if (!/^[A-Z0-9]{2,10}-[1-9][0-9]*$/.test(key)) throw new CliError("errors.usage", EXIT.usage, {}, "USAGE");
|
|
59665
|
+
code = await run2(["start", key], cwd);
|
|
59666
|
+
break;
|
|
59667
|
+
}
|
|
59668
|
+
case "doctor":
|
|
59669
|
+
code = await run2(["doctor"], cwd);
|
|
59670
|
+
if (!d.leaving?.() && (code !== EXIT.ok || current2.repair || current2.stateError) && await confirm2(t("menu.repair", { command: `fleek ${repair.join(" ")}` }))) code = await run2(repair, cwd);
|
|
59671
|
+
break;
|
|
59672
|
+
case "connections":
|
|
59673
|
+
refresh = false;
|
|
59674
|
+
code = await connect(false);
|
|
59675
|
+
break;
|
|
59676
|
+
case "help":
|
|
59677
|
+
refresh = false;
|
|
59678
|
+
code = await run2(["help"]);
|
|
59679
|
+
break;
|
|
59680
|
+
}
|
|
59681
|
+
} catch (error) {
|
|
59682
|
+
d.report(error);
|
|
59683
|
+
}
|
|
59684
|
+
if (d.leaving?.()) return code;
|
|
59685
|
+
out.line();
|
|
59686
|
+
if (refresh) state = void 0;
|
|
59361
59687
|
}
|
|
59362
59688
|
}
|
|
59363
59689
|
|
|
@@ -59731,6 +60057,10 @@ var Context = class {
|
|
|
59731
60057
|
fetch;
|
|
59732
60058
|
now;
|
|
59733
60059
|
headerShown = false;
|
|
60060
|
+
/** Bare `fleek` is an application: an update hint once, and these two end it after the current action. */
|
|
60061
|
+
updateChecked = false;
|
|
60062
|
+
agentRan = false;
|
|
60063
|
+
appQuit = false;
|
|
59734
60064
|
store;
|
|
59735
60065
|
boundProfile;
|
|
59736
60066
|
/** The look of human lines (colours only for a TTY, never with --json). */
|
|
@@ -60034,7 +60364,7 @@ async function confirmLocal(ctx, lines) {
|
|
|
60034
60364
|
const rl = createInterface2({ input: process.stdin, output: process.stderr });
|
|
60035
60365
|
try {
|
|
60036
60366
|
for (const line of lines.slice(0, -1)) ctx.out.error(line);
|
|
60037
|
-
const answer2 = await rl
|
|
60367
|
+
const answer2 = await askLine(rl, `${ctx.out.render(ctx.s.question(lines.at(-1) ?? ""), "err")} `);
|
|
60038
60368
|
return /^(?:j|ja|y|yes)$/i.test(answer2.trim());
|
|
60039
60369
|
} finally {
|
|
60040
60370
|
rl.close();
|
|
@@ -60394,7 +60724,8 @@ async function dispatch(ctx, positionals, values, exec, passthrough) {
|
|
|
60394
60724
|
displayName: profile?.needsLogin ? void 0 : profile?.displayName
|
|
60395
60725
|
}, terminal, ctx.t);
|
|
60396
60726
|
}
|
|
60397
|
-
if (!["update", "uninstall", "mcp", "listen", "help", "login", "setup"].includes(command ?? "") && !(command === "kit" && sub === "run") && !values.help) {
|
|
60727
|
+
if (!ctx.updateChecked && !["update", "uninstall", "mcp", "listen", "help", "login", "setup"].includes(command ?? "") && !(command === "kit" && sub === "run") && !values.help) {
|
|
60728
|
+
ctx.updateChecked = true;
|
|
60398
60729
|
await updateHint({
|
|
60399
60730
|
configDir: ctx.configDir,
|
|
60400
60731
|
env: ctx.env,
|
|
@@ -60408,47 +60739,19 @@ async function dispatch(ctx, positionals, values, exec, passthrough) {
|
|
|
60408
60739
|
}, ctx.deps.isTTY ?? (process.stderr.isTTY === true && process.stdin.isTTY === true));
|
|
60409
60740
|
}
|
|
60410
60741
|
if (!command && !values.help && !ctx.json && (ctx.deps.isTTY ?? (process.stdin.isTTY === true && (ctx.deps.stdout ?? process.stdout).isTTY === true))) {
|
|
60411
|
-
let
|
|
60412
|
-
const found = await resolveBinding(ctx.profiles, ctx.configDir, { flag: ctx.profileFlag, env: ctx.env, cwd: ctx.deps.cwd ?? process.cwd(), allowCurrent: true }).catch(() => {
|
|
60413
|
-
stateError = true;
|
|
60414
|
-
return null;
|
|
60415
|
-
});
|
|
60416
|
-
const profile = found?.profile ?? await ctx.profiles.current().catch(() => null);
|
|
60417
|
-
const checkouts = profile ? await new CheckoutIndex(ctx.configDir, profile.key).entries().catch(() => {
|
|
60418
|
-
stateError = true;
|
|
60419
|
-
return [];
|
|
60420
|
-
}) : [];
|
|
60421
|
-
const domain = profile && found?.projectId ? new KitDomain(ctx.configDir, profile.key, found.projectId) : null;
|
|
60422
|
-
let kitNeedsRepair = false;
|
|
60423
|
-
if (domain) {
|
|
60424
|
-
try {
|
|
60425
|
-
kitNeedsRepair = !await domain.current() && await domain.pulledAt() === null;
|
|
60426
|
-
} catch {
|
|
60427
|
-
stateError = true;
|
|
60428
|
-
kitNeedsRepair = true;
|
|
60429
|
-
}
|
|
60430
|
-
}
|
|
60431
|
-
const handler = await inspectSetupHandler(kitContext(ctx, values)).catch(() => {
|
|
60432
|
-
stateError = true;
|
|
60433
|
-
return null;
|
|
60434
|
-
});
|
|
60435
|
-
const repair = handler?.state === "missing" || kitNeedsRepair ? ["kit", "setup"] : void 0;
|
|
60436
|
-
const resume = profile && !profile.needsLogin && found?.projectId ? await ctx.session().then(async ({ client }) => {
|
|
60437
|
-
const inbox = (await client.callTool(WIRE.inbox, { limit: 25, kinds: ["claim"], teamId: found.projectId })).structured;
|
|
60438
|
-
const rows = Array.isArray(inbox.items) ? inbox.items : [];
|
|
60439
|
-
return rows.find((row) => row.kind === "claim" && typeof row.identifier === "string" && /^[A-Z0-9]{2,10}-[1-9][0-9]*$/.test(row.identifier))?.identifier;
|
|
60440
|
-
}).catch(() => void 0) : void 0;
|
|
60742
|
+
let leaving = false;
|
|
60441
60743
|
return guidedMenu({
|
|
60442
|
-
resume,
|
|
60443
|
-
stateError,
|
|
60444
60744
|
out: ctx.out,
|
|
60445
|
-
t: ctx.t,
|
|
60745
|
+
t: (key, params) => ctx.t(key, params),
|
|
60446
60746
|
ask: orcaDeps(ctx).ask,
|
|
60447
|
-
|
|
60448
|
-
|
|
60449
|
-
|
|
60450
|
-
|
|
60747
|
+
...selectFor(ctx),
|
|
60748
|
+
state: (cwd) => menuState(ctx, values, cwd),
|
|
60749
|
+
leaving: () => leaving,
|
|
60750
|
+
report: (error) => {
|
|
60751
|
+
reportFailure(ctx.out, ctx.t, error, false);
|
|
60752
|
+
},
|
|
60451
60753
|
connect: async () => {
|
|
60754
|
+
const profile = await ctx.profiles.current().catch(() => null);
|
|
60452
60755
|
const origin = profile ? webOrigin(profile) : "https://app.onfleek.app";
|
|
60453
60756
|
if (!origin) {
|
|
60454
60757
|
ctx.out.line(ctx.t("menu.setupExternal"));
|
|
@@ -60462,7 +60765,13 @@ async function dispatch(ctx, positionals, values, exec, passthrough) {
|
|
|
60462
60765
|
const target = cwd ? new Context({ ...ctx.deps, cwd }, false, ctx.profileFlag, ctx.languageFlag) : ctx;
|
|
60463
60766
|
const parsed = parseArgs({ args, options: OPTIONS, allowPositionals: true });
|
|
60464
60767
|
target.headerShown = ctx.headerShown;
|
|
60465
|
-
|
|
60768
|
+
target.updateChecked = true;
|
|
60769
|
+
if (target !== ctx && ctx.headerShown) target.out.indentHumanOutput();
|
|
60770
|
+
try {
|
|
60771
|
+
return await dispatch(target, parsed.positionals, { profile: values.profile, language: values.language, ...parsed.values, yes: false }, null, null);
|
|
60772
|
+
} finally {
|
|
60773
|
+
leaving = target.agentRan || target.appQuit;
|
|
60774
|
+
}
|
|
60466
60775
|
}
|
|
60467
60776
|
});
|
|
60468
60777
|
}
|
|
@@ -60750,6 +61059,82 @@ async function mcpProxy(ctx, args, values) {
|
|
|
60750
61059
|
...ctx.deps.proxyRetryDelaysMs ? { retryDelaysMs: ctx.deps.proxyRetryDelaysMs } : {}
|
|
60751
61060
|
});
|
|
60752
61061
|
}
|
|
61062
|
+
function selectFor(ctx) {
|
|
61063
|
+
const stdin = ctx.deps.stdin ?? process.stdin, stdout = ctx.deps.stdout ?? process.stdout;
|
|
61064
|
+
if (ctx.json || !isKeyInput(stdin) || stdout.isTTY !== true || ctx.env.TERM === "dumb") return {};
|
|
61065
|
+
return { select: async (options) => {
|
|
61066
|
+
const result = await selectList({ stdin, stdout, out: ctx.out, t: ctx.t }, options);
|
|
61067
|
+
if (result.kind === "abort") ctx.appQuit = true;
|
|
61068
|
+
return result;
|
|
61069
|
+
} };
|
|
61070
|
+
}
|
|
61071
|
+
function askLine(rl, question) {
|
|
61072
|
+
return new Promise((resolve9, reject) => {
|
|
61073
|
+
rl.once("close", () => resolve9(""));
|
|
61074
|
+
rl.question(question).then(resolve9, reject);
|
|
61075
|
+
});
|
|
61076
|
+
}
|
|
61077
|
+
var RESUME_READ_MS = 3e3;
|
|
61078
|
+
async function menuState(ctx, values, cwd) {
|
|
61079
|
+
let stateError = false;
|
|
61080
|
+
const folder = cwd ?? ctx.deps.cwd ?? process.cwd();
|
|
61081
|
+
const found = await resolveBinding(ctx.profiles, ctx.configDir, { flag: ctx.profileFlag, env: ctx.env, cwd: folder, allowCurrent: true }).catch(() => {
|
|
61082
|
+
stateError = true;
|
|
61083
|
+
return null;
|
|
61084
|
+
});
|
|
61085
|
+
const profile = found?.profile ?? await ctx.profiles.current().catch(() => null);
|
|
61086
|
+
if (profile?.language && !ctx.languageFlag) ctx.t = translator(profile.language);
|
|
61087
|
+
const keys = profile ? new ProjectKeyIndex(ctx.configDir, profile.key) : null;
|
|
61088
|
+
const keyOf = async (project2) => await keys?.keyFor(project2).catch(() => null) ?? void 0;
|
|
61089
|
+
const entries = profile ? await new CheckoutIndex(ctx.configDir, profile.key).entries().catch(() => {
|
|
61090
|
+
stateError = true;
|
|
61091
|
+
return [];
|
|
61092
|
+
}) : [];
|
|
61093
|
+
const checkouts = (await Promise.all(entries.map(async ([path, project2]) => {
|
|
61094
|
+
if (!await stat16(path).then((info) => info.isDirectory(), () => false)) return null;
|
|
61095
|
+
const key = await keyOf(project2);
|
|
61096
|
+
return { path, label: displayPath(path, ctx.home, ctx.env), ...key ? { project: key } : {} };
|
|
61097
|
+
}))).filter((entry) => entry !== null);
|
|
61098
|
+
const domain = profile && found?.projectId ? new KitDomain(ctx.configDir, profile.key, found.projectId) : null;
|
|
61099
|
+
let kitNeedsRepair = false;
|
|
61100
|
+
if (domain) {
|
|
61101
|
+
try {
|
|
61102
|
+
kitNeedsRepair = !await domain.current() && await domain.pulledAt() === null;
|
|
61103
|
+
} catch {
|
|
61104
|
+
stateError = true;
|
|
61105
|
+
kitNeedsRepair = true;
|
|
61106
|
+
}
|
|
61107
|
+
}
|
|
61108
|
+
const handler = await inspectSetupHandler(kitContext(ctx, values)).catch(() => {
|
|
61109
|
+
stateError = true;
|
|
61110
|
+
return null;
|
|
61111
|
+
});
|
|
61112
|
+
const signedIn = !!profile && !profile.needsLogin;
|
|
61113
|
+
let resume;
|
|
61114
|
+
if (signedIn && found?.projectId) {
|
|
61115
|
+
const read2 = ctx.sessionFor(profile).then(async ({ client }) => {
|
|
61116
|
+
const inbox = (await client.callTool(WIRE.inbox, { limit: 25, kinds: ["claim"], teamId: found.projectId })).structured;
|
|
61117
|
+
const rows = Array.isArray(inbox.items) ? inbox.items : [];
|
|
61118
|
+
return rows.find((row) => row.kind === "claim" && typeof row.identifier === "string" && /^[A-Z0-9]{2,10}-[1-9][0-9]*$/.test(row.identifier))?.identifier;
|
|
61119
|
+
}).catch(() => void 0);
|
|
61120
|
+
let timer;
|
|
61121
|
+
resume = await Promise.race([read2, new Promise((resolve9) => {
|
|
61122
|
+
timer = setTimeout(() => resolve9(void 0), RESUME_READ_MS);
|
|
61123
|
+
})]);
|
|
61124
|
+
clearTimeout(timer);
|
|
61125
|
+
}
|
|
61126
|
+
const project = found?.projectId ? await keyOf(found.projectId) : void 0;
|
|
61127
|
+
const context = signedIn ? [profile.workspace.name, project, displayPath(folder, ctx.home, ctx.env)].filter(Boolean).map((part) => neutralizeLine(part)).join(" · ") : void 0;
|
|
61128
|
+
return {
|
|
61129
|
+
signedIn,
|
|
61130
|
+
bound: !!found?.projectId,
|
|
61131
|
+
stateError,
|
|
61132
|
+
checkouts,
|
|
61133
|
+
...resume ? { resume } : {},
|
|
61134
|
+
...context ? { context } : {},
|
|
61135
|
+
...handler?.state === "missing" || kitNeedsRepair ? { repair: true } : {}
|
|
61136
|
+
};
|
|
61137
|
+
}
|
|
60753
61138
|
function orcaDeps(ctx) {
|
|
60754
61139
|
return {
|
|
60755
61140
|
out: ctx.out,
|
|
@@ -60768,11 +61153,12 @@ function orcaDeps(ctx) {
|
|
|
60768
61153
|
const { createInterface: createInterface2 } = await import("node:readline/promises");
|
|
60769
61154
|
const rl = createInterface2({ input: process.stdin, output: ctx.json ? process.stderr : process.stdout });
|
|
60770
61155
|
try {
|
|
60771
|
-
return await rl
|
|
61156
|
+
return await askLine(rl, `${ctx.out.render(ctx.out.style.question(question), ctx.json ? "err" : "out")} `);
|
|
60772
61157
|
} finally {
|
|
60773
61158
|
rl.close();
|
|
60774
61159
|
}
|
|
60775
61160
|
}),
|
|
61161
|
+
...selectFor(ctx),
|
|
60776
61162
|
...ctx.deps.mutationBackoffMs !== void 0 ? { backoffMs: ctx.deps.mutationBackoffMs } : {}
|
|
60777
61163
|
};
|
|
60778
61164
|
}
|
|
@@ -60789,7 +61175,11 @@ async function start(ctx, key, values) {
|
|
|
60789
61175
|
...orcaDeps(ctx),
|
|
60790
61176
|
...ctx.deps.linkDialog ? { dialog: ctx.deps.linkDialog } : {},
|
|
60791
61177
|
kitReady: async (agent, found) => !!(await new KitDomain(ctx.configDir, found.profile.key, found.projectId).current())?.state.targets[agent],
|
|
60792
|
-
runAgent: (agent, args, found) =>
|
|
61178
|
+
runAgent: async (agent, args, found) => {
|
|
61179
|
+
const code = await kitRun(kitContext(ctx, values, { profile: found.profile, projectId: found.projectId, source: "repo", root: found.root }), agent, { project: found.projectId }, args);
|
|
61180
|
+
ctx.agentRan = code !== 127;
|
|
61181
|
+
return code;
|
|
61182
|
+
}
|
|
60793
61183
|
};
|
|
60794
61184
|
return key ? fleekStart(deps, key, own4) : orcaPick(deps, own4, (chosen) => fleekStart(deps, chosen, own4));
|
|
60795
61185
|
}
|
|
@@ -61080,6 +61470,31 @@ async function setupDeveloper(ctx, code, values) {
|
|
|
61080
61470
|
}
|
|
61081
61471
|
}, code, values);
|
|
61082
61472
|
}
|
|
61473
|
+
function reportFailure(out, t, error, json2) {
|
|
61474
|
+
const errno = error?.code;
|
|
61475
|
+
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");
|
|
61476
|
+
if (json2) out.json({ error: failure2.code ?? failure2.key, ...Object.keys(failure2.params).length ? { details: failure2.params } : {} });
|
|
61477
|
+
else {
|
|
61478
|
+
const params = Object.fromEntries(Object.entries(failure2.params).map(([key, value]) => [key, typeof value === "string" ? neutralizeLine(value) : value]));
|
|
61479
|
+
let friendlyKey = failure2 instanceof ToolError && ["RATE_LIMITED", "ACCESS_DENIED", "CONFLICT", "TRANSITION_DENIED"].includes(failure2.code ?? "") ? `errors.server.${failure2.code}` : failure2.key;
|
|
61480
|
+
if (failure2.code === "KIT_INVALID" || failure2.code === "KIT_UNSIGNED") {
|
|
61481
|
+
const reason = String(failure2.params.reason ?? "");
|
|
61482
|
+
const kind = kitRefusalCategory(failure2.code, reason);
|
|
61483
|
+
friendlyKey = `errors.kitRefused.${kind}`;
|
|
61484
|
+
}
|
|
61485
|
+
out.error(out.style.fail(redact(t(friendlyKey, params))));
|
|
61486
|
+
if (failure2 instanceof ToolError && failure2.code === "TRANSITION_DENIED") {
|
|
61487
|
+
const details = failure2.details;
|
|
61488
|
+
const key = typeof details?.reason === "string" ? `errors.transition.${details.reason}` : "";
|
|
61489
|
+
if (Object.hasOwn(EN, key)) out.error(t(key));
|
|
61490
|
+
}
|
|
61491
|
+
const suggestion = failure2.suggestion;
|
|
61492
|
+
if (suggestion) out.error(t("errors.didYouMean", { command: out.style.cmd(suggestion) }));
|
|
61493
|
+
if (failure2.code === "KIT_INVALID" || failure2.code === "KIT_UNSIGNED") out.error(out.style.dim(redact(t("errors.kitReason", { ...params, reason: params.reason ?? failure2.code }))));
|
|
61494
|
+
if (`${friendlyKey}.next` in EN) out.error(` ${t("next.step", { command: out.style.cmd(redact(t(`${friendlyKey}.next`, params))) })}`);
|
|
61495
|
+
}
|
|
61496
|
+
return failure2;
|
|
61497
|
+
}
|
|
61083
61498
|
async function main(argv, deps = {}) {
|
|
61084
61499
|
const env = deps.env ?? process.env;
|
|
61085
61500
|
let t = translator(locale(env));
|
|
@@ -61110,30 +61525,7 @@ async function main(argv, deps = {}) {
|
|
|
61110
61525
|
context = new Context(deps, json2, parsed.values.profile, parsed.values.language === "en" || parsed.values.language === "de" ? parsed.values.language : void 0);
|
|
61111
61526
|
return await dispatch(context, parsed.positionals, parsed.values, exec, passthrough);
|
|
61112
61527
|
} catch (error) {
|
|
61113
|
-
|
|
61114
|
-
const errorOut = context?.out ?? out;
|
|
61115
|
-
const errno = error?.code;
|
|
61116
|
-
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");
|
|
61117
|
-
if (json2) errorOut.json({ error: failure2.code ?? failure2.key, ...Object.keys(failure2.params).length ? { details: failure2.params } : {} });
|
|
61118
|
-
else {
|
|
61119
|
-
const params = Object.fromEntries(Object.entries(failure2.params).map(([key, value]) => [key, typeof value === "string" ? neutralizeLine(value) : value]));
|
|
61120
|
-
let friendlyKey = failure2 instanceof ToolError && ["RATE_LIMITED", "ACCESS_DENIED", "CONFLICT", "TRANSITION_DENIED"].includes(failure2.code ?? "") ? `errors.server.${failure2.code}` : failure2.key;
|
|
61121
|
-
if (failure2.code === "KIT_INVALID" || failure2.code === "KIT_UNSIGNED") {
|
|
61122
|
-
const reason = String(failure2.params.reason ?? "");
|
|
61123
|
-
const kind = kitRefusalCategory(failure2.code, reason);
|
|
61124
|
-
friendlyKey = `errors.kitRefused.${kind}`;
|
|
61125
|
-
}
|
|
61126
|
-
errorOut.error(errorOut.style.fail(redact(t(friendlyKey, params))));
|
|
61127
|
-
if (failure2 instanceof ToolError && failure2.code === "TRANSITION_DENIED") {
|
|
61128
|
-
const details = failure2.details;
|
|
61129
|
-
const key = typeof details?.reason === "string" ? `errors.transition.${details.reason}` : "";
|
|
61130
|
-
if (Object.hasOwn(EN, key)) errorOut.error(t(key));
|
|
61131
|
-
}
|
|
61132
|
-
const suggestion = failure2.suggestion;
|
|
61133
|
-
if (suggestion) errorOut.error(t("errors.didYouMean", { command: errorOut.style.cmd(suggestion) }));
|
|
61134
|
-
if (failure2.code === "KIT_INVALID" || failure2.code === "KIT_UNSIGNED") errorOut.error(errorOut.style.dim(redact(t("errors.kitReason", { ...params, reason: params.reason ?? failure2.code }))));
|
|
61135
|
-
if (`${friendlyKey}.next` in EN) errorOut.error(` ${t("next.step", { command: errorOut.style.cmd(redact(t(`${friendlyKey}.next`, params))) })}`);
|
|
61136
|
-
}
|
|
61528
|
+
const failure2 = reportFailure(context?.out ?? out, context?.t ?? t, error, json2);
|
|
61137
61529
|
if (["listen", "mcp"].includes(commandName ?? "") && failure2.code === "ACCESS_DENIED") return EXIT.accessDenied;
|
|
61138
61530
|
return failure2.exitCode;
|
|
61139
61531
|
}
|