@logic-joe/fleek 0.2.11 → 0.2.13

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.
Files changed (2) hide show
  1. package/dist/fleek.mjs +478 -80
  2. package/package.json +1 -1
package/dist/fleek.mjs CHANGED
@@ -1055,7 +1055,8 @@ var require_claims = __commonJS({
1055
1055
  "../types/dist/agent-platform/claims.js"(exports) {
1056
1056
  "use strict";
1057
1057
  Object.defineProperty(exports, "__esModule", { value: true });
1058
- exports.CLAIM_QUOTAS = exports.AGENT_CONVENTION_DEFAULTS = exports.ANSWER_ASSURANCE_KINDS = exports.ISSUE_COMMENT_KINDS = exports.CLAIM_TTL_LIMITS = exports.CLAIM_END_REASONS_RETURNING_TO_POOL = exports.CLAIM_OUTCOME_END_REASON = exports.CLAIM_END_REASONS = exports.CLAIM_RELEASE_OUTCOMES = exports.CLAIM_COMPLETE_OUTCOMES = exports.CLAIM_PURPOSES = void 0;
1058
+ exports.CLAIM_QUOTAS = exports.AGENT_CONVENTION_DEFAULTS = exports.ANSWER_ASSURANCE_KINDS = exports.ISSUE_COMMENT_KINDS = exports.CLAIM_TTL_LIMITS = exports.CLAIM_END_REASONS_RETURNING_TO_POOL = exports.WORK_DELIVERY_SHA = exports.WORK_DELIVERY_BRANCH = exports.WORK_DELIVERY_LIMITS = exports.CLAIM_STATE_KEPT_REASONS = exports.CLAIM_OUTCOME_END_REASON = exports.CLAIM_END_REASONS = exports.CLAIM_RELEASE_OUTCOMES = exports.CLAIM_COMPLETE_OUTCOMES = exports.CLAIM_PURPOSES = void 0;
1059
+ exports.validDeliveryBranch = validDeliveryBranch2;
1059
1060
  exports.CLAIM_PURPOSES = ["work", "review"];
1060
1061
  exports.CLAIM_COMPLETE_OUTCOMES = ["done", "partial", "handed_off"];
1061
1062
  exports.CLAIM_RELEASE_OUTCOMES = ["paused", "not_doable"];
@@ -1076,6 +1077,21 @@ var require_claims = __commonJS({
1076
1077
  paused: "released",
1077
1078
  not_doable: "released"
1078
1079
  };
1080
+ exports.CLAIM_STATE_KEPT_REASONS = [
1081
+ "agents_may_complete_off",
1082
+ "target_unavailable",
1083
+ "rules_changed",
1084
+ "review_not_allowed",
1085
+ "state_changed",
1086
+ "edit_right_missing",
1087
+ "transition_denied"
1088
+ ];
1089
+ exports.WORK_DELIVERY_LIMITS = { branchChars: 200 };
1090
+ exports.WORK_DELIVERY_BRANCH = /^[A-Za-z0-9][A-Za-z0-9._/-]{0,199}$/;
1091
+ exports.WORK_DELIVERY_SHA = /^[0-9a-f]{40,64}$/;
1092
+ function validDeliveryBranch2(name) {
1093
+ return exports.WORK_DELIVERY_BRANCH.test(name) && !name.includes("..") && !name.includes("//") && !name.endsWith("/") && !name.endsWith(".lock");
1094
+ }
1079
1095
  exports.CLAIM_END_REASONS_RETURNING_TO_POOL = ["released", "expired", "force_released", "owner_inactive", "revoked"];
1080
1096
  exports.CLAIM_TTL_LIMITS = { defaultMinutes: 60, minMinutes: 15, maxMinutes: 480, hardHours: 24 };
1081
1097
  exports.ISSUE_COMMENT_KINDS = ["comment", "progress", "question", "decision_request", "answer", "handoff", "result", "system"];
@@ -1609,7 +1625,10 @@ var require_error_codes = __commonJS({
1609
1625
  // ONF-190: the browser proof failed because the request's refresh cookie names ANOTHER live web session of the same user (a
1610
1626
  // sign-in on another Fleek host replaced the shared cookie) - the web client renews its session at once (selected by the
1611
1627
  // HttpExceptionFilter from a server-owned request mark, never by a thrower)
1612
- "session_mismatch"
1628
+ "session_mismatch",
1629
+ "public_visibility",
1630
+ // MCP-FIX-M: a claim-bound agent write into a completed status while the project setting "Agents may complete" is off
1631
+ "agents_may_complete_off"
1613
1632
  ];
1614
1633
  exports.WORKSPACE_APPS = ["chat", "projects", "documents", "whiteboards", "workflows"];
1615
1634
  exports.MAIL_DELIVERY_STATUSES = ["queued", "sending", "accepted", "ambiguous", "failed", "suppressed"];
@@ -1792,7 +1811,7 @@ var require_events = __commonJS({
1792
1811
  "issue.deleted": { inProcessEmitter: "issue.deleted", webhookWireEvent: "issue.deleted" }
1793
1812
  };
1794
1813
  exports.AGENT_EVENT_AGGREGATE_TYPES = ["issue", "approval", "workflow_run", "workflow_definition"];
1795
- exports.APPROVAL_EVENT_READER_METADATA = ["proposalId", "kind", "outcome"];
1814
+ exports.APPROVAL_EVENT_READER_METADATA = ["proposalId", "approvalId", "kind", "outcome"];
1796
1815
  exports.DOMAIN_EVENT_VISIBILITIES = ["private", "internal", "public"];
1797
1816
  exports.APPROVAL_STALE_REASONS = [
1798
1817
  "revision_changed",
@@ -3685,8 +3704,9 @@ var require_client_ai = __commonJS({
3685
3704
  // AGD-62 LJK-1: the acceptance verdict of `fleek_complete_work` is LJ-internal (never in the guest toolset)
3686
3705
  "acceptance",
3687
3706
  "nextStep",
3688
- // ONF-200 KNOW-A: the doc statement of `fleek_complete_work` is LJ-internal too
3689
- "knowledge"
3707
+ // ONF-200 KNOW-A: the doc statement of `fleek_complete_work` is LJ-internal too; PROTOCOL-NEXT-M: so is the delivered branch + sha
3708
+ "knowledge",
3709
+ "delivery"
3690
3710
  ];
3691
3711
  exports.CLIENT_AI_TOOLS = Object.freeze(Object.keys(exports.CLIENT_AI_TOOL_FIELDS).sort());
3692
3712
  function isClientAiTool(name) {
@@ -4632,7 +4652,7 @@ var require_setup_session = __commonJS({
4632
4652
  exports.SETUP_SESSION_TTL_MINUTES = 30;
4633
4653
  exports.SETUP_SESSION_OPEN_MAX = 10;
4634
4654
  exports.SETUP_SESSION_CLAIM_LIMIT = 10;
4635
- exports.FLEEK_CLI_SETUP_VERSION_DEFAULT = "0.2.11";
4655
+ exports.FLEEK_CLI_SETUP_VERSION_DEFAULT = "0.2.13";
4636
4656
  exports.FLEEK_CLI_PACKAGE = "@logic-joe/fleek";
4637
4657
  exports.FLEEK_CANONICAL_SERVER = "https://api.onfleek.app";
4638
4658
  exports.SETUP_CLIENT_APPS = ["claude-code", "codex", "orca", "cursor", "other"];
@@ -4675,6 +4695,8 @@ var require_setup_session = __commonJS({
4675
4695
  "assign_kit",
4676
4696
  "switch_kit",
4677
4697
  "choose_repo",
4698
+ "open_applications",
4699
+ "check_repo_access",
4678
4700
  "show_command",
4679
4701
  "review_init",
4680
4702
  "setup_review_agent",
@@ -5303,6 +5325,39 @@ var require_skill_limits = __commonJS({
5303
5325
  }
5304
5326
  });
5305
5327
 
5328
+ // ../types/dist/agent-platform/refusal-hints.js
5329
+ var require_refusal_hints = __commonJS({
5330
+ "../types/dist/agent-platform/refusal-hints.js"(exports) {
5331
+ "use strict";
5332
+ Object.defineProperty(exports, "__esModule", { value: true });
5333
+ exports.agentRefusalHint = agentRefusalHint;
5334
+ var hints = {
5335
+ public_visibility: {
5336
+ code: "HUMAN_REQUIRED",
5337
+ en: "Making a ticket public needs a person in the browser. Create it with internal visibility, then ask a person to publish it.",
5338
+ de: "Ein Ticket darf nur eine Person im Browser veröffentlichen. Erstelle es intern und bitte eine Person, es zu veröffentlichen."
5339
+ },
5340
+ release_name: {
5341
+ code: "INVALID_INPUT",
5342
+ en: "Use 1–80 plain-text characters without @, mentions, markup, links, encoded references or control characters.",
5343
+ de: "Verwende 1–80 Klartextzeichen ohne @, Erwähnungen, Markup, Links, kodierte Verweise oder Steuerzeichen."
5344
+ },
5345
+ setup_changing: {
5346
+ code: "CONFLICT",
5347
+ en: "The setup changed while it was being read, for example during an apply. Retry the setup read.",
5348
+ de: "Das Setup wurde während des Lesens geändert, etwa beim Anwenden. Lies das Setup erneut."
5349
+ }
5350
+ };
5351
+ function agentRefusalHint(code, details, locale2 = "en") {
5352
+ const reason = details?.reason;
5353
+ if (typeof reason !== "string" || !Object.hasOwn(hints, reason))
5354
+ return;
5355
+ const hint = hints[reason];
5356
+ return hint.code === code ? hint[locale2] : void 0;
5357
+ }
5358
+ }
5359
+ });
5360
+
5306
5361
  // ../types/dist/index.js
5307
5362
  var require_dist = __commonJS({
5308
5363
  "../types/dist/index.js"(exports) {
@@ -5341,6 +5396,7 @@ var require_dist = __commonJS({
5341
5396
  __exportStar(require_ticket_references(), exports);
5342
5397
  __exportStar(require_admin_todo(), exports);
5343
5398
  __exportStar(require_skill_limits(), exports);
5399
+ __exportStar(require_refusal_hints(), exports);
5344
5400
  }
5345
5401
  });
5346
5402
 
@@ -32668,6 +32724,8 @@ var require_knowledge_skeleton = __commonJS({
32668
32724
  ["agent_git_commit", "Agenten dürfen committen", "Agents may commit"],
32669
32725
  ["agent_git_push", "Agenten dürfen Feature-Branch pushen", "Agents may push a feature branch"],
32670
32726
  ["agent_git_open_mr", "Agenten dürfen MR öffnen", "Agents may open a merge request"],
32727
+ // ONF-257: merging the own MR into the base (after green checks and the other model's clean review); empty / false = a person merges
32728
+ ["agent_git_merge", "Agenten dürfen eigene MR mergen", "Agents may merge their own merge request"],
32671
32729
  ["agent_git_delete_local", "Agenten dürfen lokal aufräumen", "Agents may clean up locally"],
32672
32730
  ["agent_git_delete_remote", "Agenten dürfen Remote-Branch löschen", "Agents may delete the remote branch"],
32673
32731
  ["agent_git_stop_servers", "Agenten dürfen fremde Server stoppen", "Agents may stop other servers"]
@@ -33749,6 +33807,7 @@ var require_setup_proposal2 = __commonJS({
33749
33807
  exports.setupProposeShape = {
33750
33808
  packageId: uuid.optional(),
33751
33809
  revision: zod_1.z.number().int().min(1).optional(),
33810
+ templateName: process_template_js_1.processTemplateName.optional(),
33752
33811
  entry: zod_1.z.enum(["example", "copy", "walkthrough"]),
33753
33812
  base: exports.setupBaseRefSchema,
33754
33813
  customer: zod_1.z.union([
@@ -33777,7 +33836,7 @@ var require_setup_proposal2 = __commonJS({
33777
33836
  exports.setupProposalStatusInputSchema = zod_1.z.object({ packageId: uuid }).strict();
33778
33837
  var edge = (rule) => `${rule.fromStateKey ?? "*"}>${rule.toStateKey}`;
33779
33838
  var ACTOR_RANK = { any_member: 0, lj_role: 1, named: 2, client: 3 };
33780
- function setupRisks(base, document3) {
33839
+ function setupRisks(base, document3, invites = []) {
33781
33840
  const next = document3.process.document;
33782
33841
  const out = [];
33783
33842
  const seen = /* @__PURE__ */ new Set();
@@ -33864,7 +33923,7 @@ var require_setup_proposal2 = __commonJS({
33864
33923
  if (items(base).some((text6) => !now.includes(text6)))
33865
33924
  add({ code: "checklist_items_removed", params: { gate: role } });
33866
33925
  }
33867
- const productOwner = document3.people.some((person) => person.role === "product_owner");
33926
+ const productOwner = !(0, setup_package_js_1.setupOpenPoints)(document3, invites).includes("no_product_owner");
33868
33927
  if (!productOwner && next.rules.some((rule) => rule.actorRequirement === "named" && rule.deciderRoles.includes("product_owner")))
33869
33928
  add({ code: "no_product_owner", params: {} });
33870
33929
  return out;
@@ -36040,6 +36099,319 @@ var require_document_diff = __commonJS({
36040
36099
  }
36041
36100
  });
36042
36101
 
36102
+ // ../validation/dist/agent-error-details.js
36103
+ var require_agent_error_details = __commonJS({
36104
+ "../validation/dist/agent-error-details.js"(exports) {
36105
+ "use strict";
36106
+ Object.defineProperty(exports, "__esModule", { value: true });
36107
+ exports.agentErrorDetails = agentErrorDetails2;
36108
+ var types_1 = require_dist();
36109
+ var string4 = (value) => typeof value === "string" && value.length > 0 && value.length <= 256;
36110
+ var integer = (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
36111
+ var list2 = (value) => Array.isArray(value) && value.length <= 128 && value.every(string4);
36112
+ var oneOf3 = (values) => (value) => typeof value === "string" && values.includes(value);
36113
+ var errors = (value) => Array.isArray(value) && value.length <= 64 && value.every((item2) => item2 && typeof item2 === "object" && !Array.isArray(item2) && Object.keys(item2).length === 2 && typeof item2.path === "string" && item2.path.length <= 256 && (item2.path === "" || item2.path.startsWith("/")) && typeof item2.code === "string" && /^[A-Z][A-Z0-9_]{0,63}$/.test(item2.code));
36114
+ var changeRequest = (value) => typeof value === "string" && value.length > 0 && value.length <= 500;
36115
+ var typeKeyBytes = (value) => typeof value === "string" && value.length > 0 && (0, types_1.issueTypeJsonBytes)(value) <= types_1.ISSUE_TYPE_LIMITS.entryKeyBytes;
36116
+ var typeKeyList = (value) => Array.isArray(value) && value.length <= types_1.ISSUE_TYPE_LIMITS.entries && value.every(typeKeyBytes);
36117
+ var uuid = (value) => typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(value);
36118
+ var personRef = (value) => value === null || typeof value === "string" && value.length > 0 && value.length <= 64;
36119
+ var transitionKeys = (value) => Array.isArray(value) && value.length <= 32 && value.every((item2) => typeof item2 === "string" && item2.length > 0 && item2.length <= 64 && /^[A-Za-z0-9_.:-]+$/.test(item2) && ([...types_1.TRANSITION_CONDITIONS, ...types_1.TRANSITION_REQUIRED_FIELDS].includes(item2) || /^[a-z0-9_.:-]+$/.test(item2)));
36120
+ var bindingField = (value) => typeof value === "string" && value.length <= 130 && (/^state:(?:[a-z][a-z0-9_]{0,31}|\+[0-9a-f-]{36})\.(?:role|gate|omitted)$/.test(value) || /^rule:\+[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(value) || /^rule:(?:\*|[a-z][a-z0-9_]{0,31})>[a-z][a-z0-9_]{0,31}$/.test(value) || ["phases", "roles.defaultRole", "routeOptions", "clarification.maxQuestions", "clarification.maxQuestionsPerRound", "clarification.maxRounds", "clarification.answerWithinHours", "clarification.handoffRouteKey", "clarification.handoffUserId"].includes(value));
36121
+ var schema = {
36122
+ APPROVAL_EXPIRED: {
36123
+ id: uuid,
36124
+ workspaceId: uuid,
36125
+ requesterId: uuid,
36126
+ toolName: (value) => typeof value === "string" && /^fleek_[a-z0-9_]{1,100}$/.test(value),
36127
+ createdAt: (value) => typeof value === "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(value),
36128
+ expiresAt: (value) => typeof value === "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(value),
36129
+ outcome: oneOf3(["expired", "approved", "denied", "consumed"])
36130
+ },
36131
+ TICKET_TEXT_LIMIT: {},
36132
+ TICKET_TEXT_FORMAT: {},
36133
+ TICKET_TEXT_LOSSY_REPLACEMENT: {},
36134
+ ACCESS_DENIED: { reason: oneOf3(["approval_denied", "field_right", "variant_admin"]), field: bindingField, changeRequest },
36135
+ // ENGINE-AUTHORITY: engine setup refusals (`workflows.engine.*`) - closed lists only
36136
+ CONFLICT: {
36137
+ state: oneOf3(types_1.WORKFLOW_ENGINE_STATES),
36138
+ stoppedReason: oneOf3(types_1.WORKFLOW_ENGINE_STOPPED_REASONS),
36139
+ reason: oneOf3(["setup_changing", "releases_disabled", "release_closed", "name_taken", "active_limit", "too_many_open", "engine_authority_unavailable", "engine_not_admitted", "hidden_bindings", ...types_1.WORK_REQUEST_CONFLICT_REASONS, ...types_1.TRIAGE_CONFLICT_REASONS, ...types_1.KIT_CONFLICT_REASONS, ...types_1.STANDING_CONFLICT_REASONS, ...types_1.SETUP_CONFLICT_REASONS, ...types_1.SETUP_PROPOSAL_CONFLICT_REASONS, ...types_1.KNOWLEDGE_SETUP_REASONS, ...types_1.PROJECT_INIT_CONFLICT_REASONS, ...types_1.CUSTOMER_PROPOSAL_CONFLICT_REASONS, ...types_1.KNOWLEDGE_INGEST_REASONS, ...types_1.ACCESS_REQUEST_CONFLICT_REASONS, ...types_1.SERVICE_ACCOUNT_CONFLICT_REASONS, ...types_1.SETUP_SESSION_CONFLICT_REASONS]),
36140
+ index: integer,
36141
+ statementId: uuid,
36142
+ // INGEST-RELEASE-UX: the draft parent page a release cannot publish along (`parent_unpublished`; only a page the caller can view)
36143
+ parentId: uuid,
36144
+ // PINIT-FIX-2: the application slot page a PROJECT-INIT adoption refused (closed list, no id)
36145
+ slot: oneOf3(types_1.KNOWLEDGE_APPLICATION_SLOTS),
36146
+ statementIds: (value) => Array.isArray(value) && value.length <= 200 && value.every(uuid),
36147
+ fields: (value) => Array.isArray(value) && value.length <= 4 && value.every(oneOf3(["title", "summary", "diagram", "page", "parent"]))
36148
+ },
36149
+ // PRIVACY-WORKCTX: additive `holderRef` (person ref of the holder, null without a handle key / release owner)
36150
+ ALREADY_CLAIMED: { holderLabel: string4, expiresAt: string4, holderRef: personRef },
36151
+ CLAIMED_BY_OTHER: { holderLabel: string4, expiresAt: string4, holderRef: personRef },
36152
+ CLAIM_REQUIRED: { issueIds: list2 },
36153
+ RENEW_LIMIT: { hardExpiresAt: string4 },
36154
+ NOT_READY: { readySelector: string4 },
36155
+ REVISION_CONFLICT: { currentRevision: integer },
36156
+ STATE_CONFLICT: { currentStateVersion: integer },
36157
+ TYPED_COMMENT_IMMUTABLE: { kind: string4 },
36158
+ // PRIVACY-WORKCTX: `assigneeId`, `userIds`, `userId` = wire names of declared person inputs (uniform refusal; never a value);
36159
+ // P2: the workflow person inputs `botUserId`, `designerUserIds`, `ownerUserId`, `user` (spec / edit `assign.user`)
36160
+ INVALID_INPUT: {
36161
+ field: oneOf3([
36162
+ "releaseId",
36163
+ "projectReleaseId",
36164
+ "moveOpenTo",
36165
+ "targetDate",
36166
+ "addressees",
36167
+ "options",
36168
+ "parent",
36169
+ "artifacts",
36170
+ "toUserId",
36171
+ "optionId",
36172
+ "assigneeId",
36173
+ "userIds",
36174
+ "userId",
36175
+ "botUserId",
36176
+ "designerUserIds",
36177
+ "ownerUserId",
36178
+ "user",
36179
+ "data",
36180
+ "inputs",
36181
+ "value",
36182
+ // A2A-DELIVERY AD-1 input fields
36183
+ "after",
36184
+ "agent",
36185
+ "delegateAgent",
36186
+ "neededBy",
36187
+ "pickupMinutes",
36188
+ "question",
36189
+ "teamId",
36190
+ "toAgent",
36191
+ // ONF-142 (Codex B1): a referenced create-dialog image that cannot be bound (foreign, expired, unknown) refuses the create
36192
+ "attachmentIds",
36193
+ // A2A-DELIVERY AD-1b input fields (person addresses keep the uniform PRIVACY refusal shape)
36194
+ "person",
36195
+ "forPerson",
36196
+ "requester",
36197
+ "for",
36198
+ "title",
36199
+ "description",
36200
+ "display",
36201
+ "scope",
36202
+ "kinds",
36203
+ "requestId",
36204
+ // AGD TEAM-RULES-a1: a transition plan over its bounds (TRANSITION_PLAN_LIMITS); a1.2 team process documents (N1 bounds,
36205
+ // shape, states of the team, live deciders)
36206
+ "issueIds",
36207
+ "body",
36208
+ "deciderUserIds",
36209
+ "deciders",
36210
+ "memberRoles",
36211
+ "phases",
36212
+ "rules",
36213
+ "states",
36214
+ // TEAMS-PROJECTS TP-4: Team (user group) create / rename
36215
+ "handle",
36216
+ // AGD CLARIFY-a: handoff (`assignTo` staff only, `reason` derived server-side) and the policy's escalation person
36217
+ "assignTo",
36218
+ "reason",
36219
+ "handoffUserId",
36220
+ // TES-219: a page's explicit space differs from its parent's space (documents.create / knowledge.createPage)
36221
+ "spaceId",
36222
+ // AGD GUIDE-a1: guidance version entries (bounded page list) and pin targets; a2: a role the server did not derive
36223
+ "documentIds",
36224
+ "versionId",
36225
+ "role",
36226
+ // AGD WORK-FOLDER-a: an assessment item (with `index`)
36227
+ "items",
36228
+ "subjectIssueId",
36229
+ "targetTeamId",
36230
+ "targetProjectId",
36231
+ // AGD TRIAGE-a: the route field of an issue write, classification inputs, route option documents
36232
+ "statePools",
36233
+ "deciderPoolIds",
36234
+ "fieldKeys",
36235
+ "choices",
36236
+ "clarification",
36237
+ "stateMap",
36238
+ "deliveryRoute",
36239
+ "duplicates",
36240
+ "type",
36241
+ "route",
36242
+ "priority",
36243
+ "readinessAssessmentId",
36244
+ "options",
36245
+ // AGD QUICKVIEW-a: "Meine Arbeit" paging / navigation (sealed cursor, kind filter, page size) and the guest preview flag
36246
+ "cursor",
36247
+ "kind",
36248
+ "limit",
36249
+ "view",
36250
+ "query",
36251
+ // SKILL-REQ bounded fields: names of inputs only, never stored text.
36252
+ "key",
36253
+ "name",
36254
+ "url",
36255
+ "label",
36256
+ "sourceUrl",
36257
+ "packageVersion",
36258
+ "purpose",
36259
+ "installHints",
36260
+ "item",
36261
+ // KITS-a admin inputs (SETTINGS-AGENTWORK-b): pin targets, host address
36262
+ "teamIds",
36263
+ "origin",
36264
+ "holder",
36265
+ // AGD WORK-FOLDER-b: the gate role of a checklist read / readiness write
36266
+ "gateRole",
36267
+ // FOCUS-MODE FM-1: a malformed UI focus parameter (`@UiFocus()`; the grammar is the only reason)
36268
+ "focus",
36269
+ // AGD CLIENT-AI-a: a field outside the guest toolset's list (closed: the guest tools' own input fields)
36270
+ ...types_1.CLIENT_AI_REFUSED_FIELDS,
36271
+ // AGENT-SCOPE (AS-1): a refused installation scope / scoped area list (`scope`, `clientGroupId`, `teamIds`, `spaceIds`, `allowedAreas`)
36272
+ ...types_1.AGENT_SCOPE_INVALID_FIELDS,
36273
+ // AGD AGENT-RELEASE-b RB-3: a standing order's target (installation not scoped to exactly the group, group not exclusive)
36274
+ ...types_1.STANDING_INVALID_FIELDS,
36275
+ ...types_1.SETUP_INVALID_FIELDS,
36276
+ ...types_1.SETUP_PROPOSAL_INVALID_FIELDS,
36277
+ // AGD SETUP-KNOW: knowledge setup writer inputs
36278
+ "area",
36279
+ "applicationId",
36280
+ "slot",
36281
+ "documentId",
36282
+ "pathHint",
36283
+ "expectedRevision",
36284
+ "condition",
36285
+ "derivedFromVersionId",
36286
+ "editSpaceIds",
36287
+ // AGD SETUP-KNOW SK-5b: customer proposal inputs
36288
+ ...types_1.CUSTOMER_PROPOSAL_INVALID_FIELDS,
36289
+ // AGD PROJECT-INIT: the summary (with `path`), selection, customer, project key, run epoch
36290
+ ...types_1.PROJECT_INIT_INVALID_FIELDS,
36291
+ // PROJ-REPO-LINK: the repository reference (never echoes the value)
36292
+ "repository",
36293
+ // AGD-62 LJK-1: the typed result's acceptance verdict (work.complete; explicit, not only through the guest refusal list)
36294
+ "acceptance",
36295
+ // DEVX-START follow-up: the delivered branch + head commit of work.complete
36296
+ "delivery",
36297
+ // KNOW-INGEST: run / submit / review inputs (names only)
36298
+ ...types_1.KNOWLEDGE_INGEST_INVALID_FIELDS,
36299
+ // AGENT-ATTACH: the file of `issues.attachFile` (names only, never the value)
36300
+ "fileName",
36301
+ "content",
36302
+ "mimeType",
36303
+ "commentId",
36304
+ // AGENT-ATTACH-2: the presigned upload of `issues.attachFileBegin` / `issues.attachFileComplete`
36305
+ "size",
36306
+ "uploadId",
36307
+ // ACCESS-REQUESTS: request / decision / self request inputs (names only)
36308
+ ...types_1.ACCESS_REQUEST_INVALID_FIELDS
36309
+ ]),
36310
+ index: integer,
36311
+ path: (value) => (0, types_1.isProjectInitPath)(value) || (0, types_1.isKnowledgeSubmitPath)(value),
36312
+ // MCP-FIX-M `handoff_target` = fleek_complete_work handoff names not exactly one of toUserId / toAgent;
36313
+ // ONF-306 (F38): `page_not_internal` / `page_not_in_project_space` / `profile_schema_missing` = a profile page binding refused for a readable page;
36314
+ // WF-TF-2 `not_target_project`; WORK-FOLDER-b `human_only` = an agent assessment named an item only a human sets
36315
+ reason: oneOf3(["release_name", ...types_1.WORK_REQUEST_INVALID_REASONS, "incompatible_work_filters", "handoff_target", "page_not_internal", "page_not_in_project_space", "profile_schema_missing", "not_target_project", "human_only", "system_item", ...types_1.SKILL_INVALID_REASONS, ...types_1.KIT_INVALID_INPUT_REASONS, ...types_1.SETUP_INVALID_REASONS, ...types_1.SETUP_PROPOSAL_INVALID_REASONS, ...types_1.KNOWLEDGE_SETUP_REASONS, ...types_1.PROJECT_INIT_INVALID_REASONS, ...types_1.KNOWLEDGE_INGEST_INVALID_REASONS]),
36316
+ maxBytes: integer,
36317
+ maxItems: integer,
36318
+ messageKey: oneOf3(["agentWorkSkills.errors.fieldLimit", "agentWorkSkills.errors.countLimit"]),
36319
+ // CFG-B4 (M2): a change draft's browser-only op names the server-built absolute settings link (`browserLink`, ?section=)
36320
+ url: (value) => typeof value === "string" && value.length <= 512 && /^https?:\/\/[^\s<>"']+\?section=[a-z-]+$/.test(value)
36321
+ },
36322
+ HUMAN_REQUIRED: { reason: oneOf3(types_1.HUMAN_REQUIRED_REASONS) },
36323
+ // W3 SETTINGS-AGENTWORK-b: closed validator reason + closed content path (never a caller key or text)
36324
+ KIT_INVALID: { reason: oneOf3(types_1.KIT_ISSUE_REASONS), path: types_1.isKitIssuePath },
36325
+ // AGD CLARIFY-a: a refused clarification question tells the agent protocol to hand off (`fleek_request_human`)
36326
+ QUOTA_EXCEEDED: { dimension: string4, limit: integer, retryAfterSeconds: integer, hint: oneOf3(["request_human"]) },
36327
+ // A2A-DELIVERY: never an identity
36328
+ ADDRESSED_TO_OTHER_AGENT: { since: string4 },
36329
+ ADDRESSED_TO_PERSON: { since: string4 },
36330
+ WORK_ITEM_TAKEN: { takenByRef: personRef },
36331
+ WORK_REQUEST_STATE: { state: oneOf3(types_1.WORK_REQUEST_DISPLAY) },
36332
+ APP_DISABLED: { app: oneOf3(types_1.WORKSPACE_APPS) },
36333
+ APPROVER_LACKS_RIGHTS: { missing: list2 },
36334
+ RUN_EXISTS: { runId: string4 },
36335
+ OUTPUTS_INVALID: { errors },
36336
+ SPEC_INVALID: { errors },
36337
+ DRAFT_CONFLICT: { currentDraftRevision: integer },
36338
+ ROLE_UNRESOLVED: { roleKey: string4 },
36339
+ ROLE_PRINCIPAL_NOT_ELIGIBLE: { userId: string4 },
36340
+ ITEM_LIMIT: { limit: integer },
36341
+ RESULT_TOO_LARGE: { limit: integer },
36342
+ APPROVAL_MODE_NOT_ALLOWED: { mode: oneOf3([...types_1.WORKFLOW_APPROVAL_MODES, "inherit"]), workspaceMode: oneOf3(types_1.WORKFLOW_APPROVAL_MODES) },
36343
+ BATCH_TOO_LARGE: { maxItems: integer, maxBytes: integer },
36344
+ WORKFLOW_NOT_STARTABLE: { reason: oneOf3(types_1.WORKFLOW_NOT_STARTABLE_REASONS) },
36345
+ WORKFLOW_TASK_RECONCILING: { retryAfterSeconds: integer },
36346
+ WORKFLOW_TASK_RESULT_REQUIRED: { missing: list2 },
36347
+ ISSUE_TYPE_NOT_ALLOWED: { type: typeKeyBytes, teamId: uuid, allowed: typeKeyList },
36348
+ ISSUE_TYPE_CATALOG_MISSING: { reason: oneOf3(types_1.ISSUE_TYPE_CATALOG_MISSING_REASONS) },
36349
+ ISSUE_TYPE_ARCHIVED: { typeId: uuid },
36350
+ ISSUE_TYPE_IS_DEFAULT: { setCount: integer },
36351
+ ISSUE_TYPE_SET_IN_USE: { teamCount: integer },
36352
+ ISSUE_TYPE_SET_INVALID: { reason: oneOf3(types_1.ISSUE_TYPE_SET_INVALID_REASONS) },
36353
+ ISSUE_TYPE_LIMIT: { limit: integer },
36354
+ // TCONN-1: allowlisted reasons / capability column names only (never provider text)
36355
+ TARGET_LOCATION_UNAVAILABLE: { reason: oneOf3(types_1.TARGET_ERROR_REASONS) },
36356
+ TARGET_CONNECTION_REAUTH: { reason: oneOf3(types_1.TARGET_ERROR_REASONS) },
36357
+ TARGET_PATH_INVALID: { reason: oneOf3(types_1.TARGET_ERROR_REASONS) },
36358
+ TARGET_FILE_TOO_LARGE: { maxBytes: integer },
36359
+ TARGET_CAPABILITY_MISSING: { reason: oneOf3(types_1.TARGET_ERROR_REASONS), capability: oneOf3(types_1.TARGET_CAPABILITIES) },
36360
+ TARGET_ACCOUNT_MISMATCH: { reason: oneOf3(types_1.TARGET_ERROR_REASONS) },
36361
+ // AGD TEAM-RULES-a1: ids / closed keys only (`missing` = condition / field keys, never content; restricted actors get none)
36362
+ // AGD-51: `openPoints` = the same closed key shape (condition / checklist keys; only for a proven unrestricted human)
36363
+ TRANSITION_DENIED: { reason: oneOf3(types_1.TRANSITION_DENIED_REASONS), toStateId: uuid, collectingStateId: uuid, missing: transitionKeys, openPoints: transitionKeys },
36364
+ TEAM_PROCESS_INVALID: { reason: oneOf3(types_1.TEAM_PROCESS_INVALID_REASONS) },
36365
+ // TES-403: `estimate` = the legacy point estimate a restricted actor never writes
36366
+ FIELD_LOCKED: { field: oneOf3([...types_1.TEAM_PROCESS_LOCKED_FIELDS, "projectReleaseId", "estimate"]) },
36367
+ // AGD COST-LIMITS-a: the unit only (never an amount)
36368
+ COST_LIMIT_REACHED: { unit: oneOf3(["tokens", "eur"]) },
36369
+ // AGD TRIAGE-a: the project only
36370
+ ROUTE_NOT_ALLOWED: { teamId: uuid },
36371
+ // AGD KNOW-MAINT-a: a count only (never the ids of changes the reviewer may not review)
36372
+ KNOWLEDGE_REVIEW_FORBIDDEN: { count: integer },
36373
+ // AGD KNOW-MAINT-b: bounds, section ids of the proposal itself and counts only (never page ids or text)
36374
+ KNOWLEDGE_RULE_SUBTREE_TOO_LARGE: { maxPages: integer },
36375
+ KNOWLEDGE_REWRITE_REQUIRED: { sectionIds: (value) => Array.isArray(value) && value.length <= 20 && value.every((item2) => typeof item2 === "string" && /^(?:block:\d{1,8}|end)$/.test(item2)) },
36376
+ KNOWLEDGE_REVIEW_PENDING: { count: integer },
36377
+ // AGD GUIDE-a: closed reasons / ids only (never a page name or text)
36378
+ GUIDANCE_INVALID: { reason: oneOf3(types_1.GUIDANCE_INVALID_REASONS), documentId: uuid },
36379
+ // AGD PROC-TEMPLATES-a: closed reason, a document member or input field (never a value), its position
36380
+ PROCESS_TEMPLATE_INVALID: { reason: oneOf3(types_1.PROCESS_TEMPLATE_INVALID_REASONS), field: (value) => bindingField(value) || oneOf3([...types_1.PROCESS_TEMPLATE_DOCUMENT_FIELDS, ...types_1.PROCESS_TEMPLATE_INPUT_FIELDS, ...types_1.TRANSITION_CONDITIONS, ...types_1.TRANSITION_REQUIRED_FIELDS])(value), index: integer },
36381
+ RULE_PAGE_BUSY: { retryAfterSeconds: integer },
36382
+ GUIDANCE_REQUIRED: { tool: oneOf3(["fleek_get_guidance"]) },
36383
+ GUIDANCE_STALE: { tool: oneOf3(["fleek_get_guidance"]) },
36384
+ // AGD WORK-FOLDER-a: the bound checklist version (null = none bound); WORK-FOLDER-b: the gate role of the fenced key
36385
+ CHECKLIST_STALE: { boundVersionId: (value) => value === null || uuid(value), gateRole: oneOf3(types_1.GUIDANCE_CHECKLIST_GATE_ROLES) },
36386
+ // AGD WORK-FOLDER-b: the closed reason only (never the object a native URL names)
36387
+ ISSUE_LINK_INVALID: { reason: oneOf3(types_1.ISSUE_LINK_INVALID_REASONS) },
36388
+ // AGENT-ATTACH: the decoded size limit of an inline agent file (the transport's own 413 carries no details)
36389
+ CONTENT_TOO_LARGE: { maxBytes: integer },
36390
+ // AGENT-ATTACH-2: the closed reason of a refused upload completion (never a storage detail)
36391
+ ATTACHMENT_UPLOAD_INVALID: { reason: oneOf3(types_1.ATTACHMENT_UPLOAD_INVALID_REASONS) }
36392
+ };
36393
+ function agentErrorDetails2(code, value) {
36394
+ if (!value || typeof value !== "object" || Array.isArray(value) || !Object.hasOwn(schema, code))
36395
+ return;
36396
+ const validators = schema[code];
36397
+ const result = {};
36398
+ for (const [name, validate] of Object.entries(validators)) {
36399
+ const field = value[name];
36400
+ if (validate(field))
36401
+ result[name] = JSON.parse(JSON.stringify(field));
36402
+ }
36403
+ let bytes = 0;
36404
+ for (const char of JSON.stringify(result)) {
36405
+ const point = char.codePointAt(0);
36406
+ bytes += point <= 127 ? 1 : point <= 2047 ? 2 : point <= 65535 ? 3 : 4;
36407
+ }
36408
+ if (!Object.keys(result).length || bytes > 4096)
36409
+ return;
36410
+ return result;
36411
+ }
36412
+ }
36413
+ });
36414
+
36043
36415
  // ../validation/dist/index.js
36044
36416
  var require_dist2 = __commonJS({
36045
36417
  "../validation/dist/index.js"(exports) {
@@ -36090,11 +36462,12 @@ var require_dist2 = __commonJS({
36090
36462
  __exportStar(require_doc_statement(), exports);
36091
36463
  __exportStar(require_document_diff(), exports);
36092
36464
  __exportStar(require_zod_compat(), exports);
36465
+ __exportStar(require_agent_error_details(), exports);
36093
36466
  }
36094
36467
  });
36095
36468
 
36096
36469
  // src/cli.ts
36097
- var import_types10 = __toESM(require_dist(), 1);
36470
+ var import_types11 = __toESM(require_dist(), 1);
36098
36471
  import { spawn as spawn9 } from "node:child_process";
36099
36472
  import { createHash as createHash9, randomBytes as randomBytes12 } from "node:crypto";
36100
36473
  import { rm as rm13 } from "node:fs/promises";
@@ -37002,6 +37375,7 @@ var EN = {
37002
37375
  "link.confirmStart": 'Start {key} "{title}" in Orca with {agent}? Task: {task}.',
37003
37376
  "errors.startForeignClaim": "{key} is being worked on by {holder} until {expires}. Nothing was started.",
37004
37377
  "errors.startReviewNoBranch": "{key}: origin has no branch with this ticket key, so nothing has been delivered for review. Nothing was started.",
37378
+ "errors.startReviewMoved": "{key}: the delivered branch {branch} moved on since the delivery ({sha} delivered, origin now at {head}). Ask the builder to deliver again. Nothing was started.",
37005
37379
  "errors.startReviewBranches": "{key}: several branches carry this ticket key: {branches}. Nothing was started.",
37006
37380
  "errors.startReviewBranches.next": "fleek start {key} after removing or renaming the other branches",
37007
37381
  "errors.startReviewRefused": "{key}: the server does not allow a review claim right now.",
@@ -37768,6 +38142,7 @@ var DE = {
37768
38142
  "link.confirmStart": "{key} „{title}“ mit {agent} in Orca starten? Auftrag: {task}.",
37769
38143
  "errors.startForeignClaim": "{key} wird gerade von {holder} bearbeitet, bis {expires}. Es wurde nichts gestartet.",
37770
38144
  "errors.startReviewNoBranch": "{key}: Auf origin gibt es keinen Branch mit diesem Ticket-Key, also wurde nichts zum Review abgeliefert. Es wurde nichts gestartet.",
38145
+ "errors.startReviewMoved": "{key}: Der abgelieferte Branch {branch} hat sich seit der Ablieferung weiterbewegt ({sha} abgeliefert, origin jetzt bei {head}). Bitte den Builder, neu abzuliefern. Es wurde nichts gestartet.",
37771
38146
  "errors.startReviewBranches": "{key}: Mehrere Branches tragen diesen Ticket-Key: {branches}. Es wurde nichts gestartet.",
37772
38147
  "errors.startReviewBranches.next": "fleek start {key}, nachdem die anderen Branches entfernt oder umbenannt sind",
37773
38148
  "errors.startReviewRefused": "{key}: Der Server erlaubt gerade keinen Review-Claim.",
@@ -39766,6 +40141,8 @@ async function serveMcp(client, options) {
39766
40141
  }
39767
40142
 
39768
40143
  // src/mcp-proxy.ts
40144
+ var import_types3 = __toESM(require_dist(), 1);
40145
+ var import_validation = __toESM(require_dist2(), 1);
39769
40146
  var PROXY_LEGACY_VERSIONS = ["2025-11-25", "2025-06-18"];
39770
40147
  var DEFAULT_VERSION = PROXY_LEGACY_VERSIONS[0];
39771
40148
  var LINE_LIMIT = 1024 * 1024;
@@ -39810,11 +40187,17 @@ function matchResponse(raw, id) {
39810
40187
  }
39811
40188
  return null;
39812
40189
  }
39813
- function retrySafe(message) {
40190
+ function retrySafe(message, readOnlyTools = /* @__PURE__ */ new Set()) {
39814
40191
  if (message.method !== "tools/call") return true;
39815
- const args = object2(message.params) ? message.params.arguments : void 0;
40192
+ const params = object2(message.params) ? message.params : void 0;
40193
+ if (params && typeof params.name === "string" && readOnlyTools.has(params.name)) return true;
40194
+ const args = params ? params.arguments : void 0;
39816
40195
  return object2(args) && typeof args.idempotencyKey === "string" && args.idempotencyKey.length > 0;
39817
40196
  }
40197
+ function readOnlyToolNames(answer2) {
40198
+ const tools = object2(answer2.result) && Array.isArray(answer2.result.tools) ? answer2.result.tools : [];
40199
+ return tools.filter((tool) => object2(tool) && typeof tool.name === "string" && object2(tool.annotations) && tool.annotations.readOnlyHint === true).map((tool) => tool.name);
40200
+ }
39818
40201
  var CODE = /^[A-Z_]{1,64}$/;
39819
40202
  var PROFILE_HINT = {
39820
40203
  PROFILE_AMBIGUOUS: "Several Fleek sign-ins are bound to this checkout: pin one with `--profile <key>` or FLEEK_PROFILE in the MCP entry.",
@@ -39837,6 +40220,7 @@ async function runProxy(options) {
39837
40220
  let session = null;
39838
40221
  let loginHinted = false;
39839
40222
  const reported = /* @__PURE__ */ new Set();
40223
+ const readOnlyTools = /* @__PURE__ */ new Set();
39840
40224
  let closed = false;
39841
40225
  const write2 = (message) => {
39842
40226
  if (closed) return;
@@ -39908,12 +40292,17 @@ async function runProxy(options) {
39908
40292
  }
39909
40293
  if (response.status >= 400) {
39910
40294
  let code = response.status === 403 ? "ACCESS_DENIED" : response.status === 413 ? "CONTENT_TOO_LARGE" : "INVALID_INPUT";
40295
+ let details;
39911
40296
  try {
39912
40297
  const parsed = JSON.parse(raw);
39913
- if (object2(parsed) && typeof parsed.error === "string" && CODE.test(parsed.error)) code = parsed.error;
40298
+ if (object2(parsed)) {
40299
+ if (typeof parsed.error === "string" && CODE.test(parsed.error)) code = parsed.error;
40300
+ if (typeof parsed.code === "string" && Object.hasOwn(import_types3.AGENT_ERROR_CODES, parsed.code) && import_types3.AGENT_ERROR_CODES[parsed.code].mcpLegacy === parsed.error) code = parsed.code;
40301
+ if (Object.hasOwn(import_types3.AGENT_ERROR_CODES, code)) details = (0, import_validation.agentErrorDetails)(code, parsed.details);
40302
+ }
39914
40303
  } catch {
39915
40304
  }
39916
- throw new Refused(proxyError(id, code, code === "ACCESS_DENIED" ? "Fleek refused the request (access denied)." : `Fleek refused the request (${code}).`));
40305
+ throw new Refused(proxyError(id, code, code === "ACCESS_DENIED" ? "Fleek refused the request (access denied)." : `Fleek refused the request (${code}).`, details ? { details } : {}));
39917
40306
  }
39918
40307
  throw new TransientError(response.status);
39919
40308
  }
@@ -39930,6 +40319,7 @@ async function runProxy(options) {
39930
40319
  try {
39931
40320
  const answer2 = await post(message, id, signal);
39932
40321
  if (answer2 && message.method === "initialize" && object2(answer2.result) && typeof answer2.result.protocolVersion === "string" && PROXY_LEGACY_VERSIONS.includes(answer2.result.protocolVersion)) version2 = answer2.result.protocolVersion;
40322
+ if (answer2 && message.method === "tools/list") for (const name of readOnlyToolNames(answer2)) readOnlyTools.add(name);
39933
40323
  if (answer2 && !signal.aborted) write2(answer2);
39934
40324
  if (answer2 && message.method === "initialize" && !object2(answer2.error)) loginHinted = false;
39935
40325
  return;
@@ -39945,7 +40335,7 @@ async function runProxy(options) {
39945
40335
  return;
39946
40336
  }
39947
40337
  const transient = error instanceof TransientError;
39948
- if (transient && attempt < retryDelays.length && retrySafe(message)) {
40338
+ if (transient && attempt < retryDelays.length && retrySafe(message, readOnlyTools)) {
39949
40339
  await new Promise((resolve9) => setTimeout(resolve9, retryDelays[attempt]));
39950
40340
  if (signal.aborted) return;
39951
40341
  continue;
@@ -39957,7 +40347,7 @@ async function runProxy(options) {
39957
40347
  options.diagnostic(`fleek mcp proxy: request failed (${code})${PROFILE_HINT[code] ? ` - ${PROFILE_HINT[code]}` : ""}`);
39958
40348
  }
39959
40349
  if (id !== null) {
39960
- write2(transient ? proxyError(id, "UNAVAILABLE", retrySafe(message) ? "Fleek is unreachable right now; retry later." : "Fleek is unreachable right now; the outcome is unknown. Retry with an idempotencyKey to repeat it safely.") : proxyError(id, code, PROFILE_HINT[code] ?? "The request failed."));
40350
+ write2(transient ? proxyError(id, "UNAVAILABLE", retrySafe(message, readOnlyTools) ? "Fleek is unreachable right now; retry later." : "Fleek is unreachable right now; the outcome is unknown. Retry with an idempotencyKey to repeat it safely.") : proxyError(id, code, PROFILE_HINT[code] ?? "The request failed."));
39961
40351
  }
39962
40352
  return;
39963
40353
  }
@@ -48099,7 +48489,7 @@ function kitContentHash(content3) {
48099
48489
  }
48100
48490
 
48101
48491
  // ../kit-format/dist/payload.js
48102
- var import_types3 = __toESM(require_dist(), 1);
48492
+ var import_types4 = __toESM(require_dist(), 1);
48103
48493
  var KIT_VERSION_PURPOSE = "fleek-kit/1";
48104
48494
  var KIT_STATUS_PURPOSE = "fleek-kit-status/1";
48105
48495
  var KIT_STATUS_STATES = ["current", "superseded", "revoked", "unsigned", "not_entitled"];
@@ -48171,7 +48561,7 @@ function parseVersionAttestationPayload(value) {
48171
48561
  workspaceId: matching(p.workspaceId, UUID, "$.workspaceId"),
48172
48562
  kitKey: kitKeyOf(p.kitKey, "$.kitKey"),
48173
48563
  kind: oneOf(p.kind, KIT_KINDS, "$.kind"),
48174
- role: oneOf(p.role, import_types3.PROJECT_MEMBER_ROLES, "$.role"),
48564
+ role: oneOf(p.role, import_types4.PROJECT_MEMBER_ROLES, "$.role"),
48175
48565
  audienceClass,
48176
48566
  clientGroupId,
48177
48567
  version: version(p.version, "$.version"),
@@ -48202,7 +48592,7 @@ function parseStatusPayload(value) {
48202
48592
  return {
48203
48593
  kitKey: kitKeyOf(e.kitKey, `${path}.kitKey`),
48204
48594
  kind: oneOf(e.kind, KIT_KINDS, `${path}.kind`),
48205
- role: oneOf(e.role, import_types3.PROJECT_MEMBER_ROLES, `${path}.role`),
48595
+ role: oneOf(e.role, import_types4.PROJECT_MEMBER_ROLES, `${path}.role`),
48206
48596
  pinnedVersion: version(e.pinnedVersion, `${path}.pinnedVersion`)
48207
48597
  };
48208
48598
  });
@@ -48900,7 +49290,7 @@ function projectFactsForStack(products, catalog = LJ_TECHNOLOGY_CATALOG) {
48900
49290
  }
48901
49291
 
48902
49292
  // src/kit-store.ts
48903
- var import_types4 = __toESM(require_dist(), 1);
49293
+ var import_types5 = __toESM(require_dist(), 1);
48904
49294
  var STATE_VERSION = 1;
48905
49295
  var GEN = /^gen-[0-9a-f]{24}$/;
48906
49296
  var corrupt2 = (path) => new CliError("errors.kitStateCorrupt", EXIT.failed, { path }, "KIT_STATE_CORRUPT");
@@ -48913,7 +49303,7 @@ function validState(value, profileKey2, projectId) {
48913
49303
  if (typeof s.workspaceId !== "string" || typeof s.issuer !== "string" || !Array.isArray(s.kits) || s.kits.length > 64) return false;
48914
49304
  if (!s.targets || typeof s.targets !== "object" || !s.checkouts || typeof s.checkouts !== "object" || !Array.isArray(s.mcp) || typeof s.checkoutMode !== "boolean") return false;
48915
49305
  for (const kit2 of s.kits) {
48916
- if (!kit2 || !isKitKey(kit2.kitKey) || !KIT_KINDS.includes(kit2.kind) || !import_types4.PROJECT_MEMBER_ROLES.includes(kit2.role) || !KIT_PLACEMENTS.includes(kit2.placement) || !Number.isSafeInteger(kit2.version) || !Number.isSafeInteger(kit2.minVersion) || typeof kit2.contentHash !== "string" || typeof kit2.versionId !== "string") return false;
49306
+ if (!kit2 || !isKitKey(kit2.kitKey) || !KIT_KINDS.includes(kit2.kind) || !import_types5.PROJECT_MEMBER_ROLES.includes(kit2.role) || !KIT_PLACEMENTS.includes(kit2.placement) || !Number.isSafeInteger(kit2.version) || !Number.isSafeInteger(kit2.minVersion) || typeof kit2.contentHash !== "string" || typeof kit2.versionId !== "string") return false;
48917
49307
  }
48918
49308
  for (const target of Object.keys(s.targets)) if (!KIT_TARGETS.includes(target)) return false;
48919
49309
  if (s.undecided !== void 0 && (!s.undecided || typeof s.undecided !== "object" || Array.isArray(s.undecided))) return false;
@@ -49678,7 +50068,7 @@ async function orcaPick(deps, values, start2) {
49678
50068
  }
49679
50069
 
49680
50070
  // src/start.ts
49681
- var import_types5 = __toESM(require_dist(), 1);
50071
+ var import_types6 = __toESM(require_dist(), 1);
49682
50072
  import { basename as basename2, dirname as dirname6, isAbsolute as isAbsolute6 } from "node:path";
49683
50073
 
49684
50074
  // src/mutation.ts
@@ -49740,13 +50130,12 @@ function causeOf(error) {
49740
50130
 
49741
50131
  // src/start.ts
49742
50132
  var AGENT = /^[a-z][a-z0-9-]{0,31}$/;
49743
- var BRANCH = /^[A-Za-z0-9][A-Za-z0-9._/-]{0,200}$/;
49744
- var validBranch = (name) => BRANCH.test(name) && !name.includes("..") && !name.includes("//") && !name.endsWith("/") && !name.endsWith(".lock");
50133
+ var validBranch = import_types6.validDeliveryBranch;
49745
50134
  var CANDIDATES_SHOWN = 10;
49746
50135
  var string3 = (value) => typeof value === "string" ? value : "";
49747
50136
  async function liveFacts(client, task) {
49748
50137
  const tools = await client.availableTools();
49749
- if (!tools.has(WIRE.context)) return { step: null, claims: [], providers: null };
50138
+ if (!tools.has(WIRE.context)) return { step: null, claims: [], providers: null, delivery: null };
49750
50139
  const context = (await client.callTool(WIRE.context, { issueId: task.id, format: "json", include: ["task", "work", "conventions"] })).structured;
49751
50140
  const work2 = object3(context.work) ? context.work : {};
49752
50141
  const claims = (Array.isArray(work2.claims) ? work2.claims : []).filter(object3).map((claim) => ({
@@ -49756,6 +50145,8 @@ async function liveFacts(client, task) {
49756
50145
  holder: object3(claim.holder) ? string3(claim.holder.text) : "",
49757
50146
  expiresAt: string3(claim.expiresAt)
49758
50147
  }));
50148
+ const recorded = object3(work2.delivery) ? work2.delivery : null;
50149
+ const delivery = recorded && typeof recorded.branch === "string" && validBranch(recorded.branch) && typeof recorded.sha === "string" && import_types6.WORK_DELIVERY_SHA.test(recorded.sha) ? { branch: recorded.branch, sha: recorded.sha, at: string3(recorded.at) } : null;
49759
50150
  const conventions = object3(context.conventions) ? context.conventions : {};
49760
50151
  const providers = Array.isArray(conventions.aiProviders) ? conventions.aiProviders.filter((entry) => typeof entry === "string") : null;
49761
50152
  const taskSection = object3(context.task) ? context.task : {};
@@ -49763,9 +50154,9 @@ async function liveFacts(client, task) {
49763
50154
  let step = null;
49764
50155
  if (stateId && tools.has("fleek_list_workflow_states")) {
49765
50156
  const state = (await pages(client, "fleek_list_workflow_states", { teamId: task.projectId }, 200)).find((row) => string3(row.id).toLowerCase() === stateId);
49766
- step = state && (0, import_types5.isOpenInStep)(state.role) ? state.role : null;
50157
+ step = state && (0, import_types6.isOpenInStep)(state.role) ? state.role : null;
49767
50158
  }
49768
- return { step, claims, providers };
50159
+ return { step, claims, providers, delivery };
49769
50160
  }
49770
50161
  function defaultAgent(providers) {
49771
50162
  return providers && providers.length && !providers.includes("anthropic") && providers.includes("openai") ? "codex" : "claude";
@@ -49820,7 +50211,14 @@ function branchesOfTicket(lsRemote, key) {
49820
50211
  const token = new RegExp(`(^|[^a-z0-9])${key.toLowerCase().replace(/[^a-z0-9-]/g, "")}($|[^a-z0-9])`, "i");
49821
50212
  return lsRemote.split("\n").map((line) => /^[0-9a-f]{40,64}\s+refs\/heads\/(\S+)$/.exec(line.trim())?.[1] ?? "").filter((name) => name && validBranch(name) && token.test(name));
49822
50213
  }
49823
- async function deliveredBranch(deps, root, key) {
50214
+ async function deliveredBranch(deps, root, key, recorded) {
50215
+ if (recorded) {
50216
+ if ((await fetchBranch(deps, root, recorded.branch)).code !== 0) throw new CliError("errors.startGit", EXIT.failed, { key, path: neutralizeLine(root) }, "GIT_FAILED");
50217
+ const head2 = /^([0-9a-f]{40,64})\s+(\S+)/.exec((await git(deps, root, ["log", "-1", "--format=%H %cI", `refs/remotes/origin/${recorded.branch}`])).stdout.trim());
50218
+ if (!head2) throw new CliError("errors.startGit", EXIT.failed, { key, path: neutralizeLine(root) }, "GIT_FAILED");
50219
+ if (head2[1] !== recorded.sha) throw new CliError("errors.startReviewMoved", EXIT.failed, { key, branch: neutralizeLine(recorded.branch), sha: recorded.sha.slice(0, 10), head: head2[1].slice(0, 10) }, "REVIEW_BRANCH_MOVED");
50220
+ return { branch: recorded.branch, sha: recorded.sha, date: /^\d{4}-\d{2}-\d{2}/.test(recorded.at) ? recorded.at.slice(0, 10) : head2[2].slice(0, 10) };
50221
+ }
49824
50222
  const remote = await git(deps, root, ["ls-remote", "--heads", "origin"]);
49825
50223
  if (remote.code !== 0) throw new CliError("errors.startGit", EXIT.failed, { key, path: neutralizeLine(root) }, "GIT_FAILED");
49826
50224
  const found = branchesOfTicket(remote.stdout, key);
@@ -49883,8 +50281,8 @@ function receiptOf(run2) {
49883
50281
  };
49884
50282
  }
49885
50283
  function promptOf(profile, task, step, role, lang, claim) {
49886
- const text6 = (0, import_types5.openInStartText)({ workspace: profile.workspace.slug, ticket: task.key, step, role, locale: lang, claim });
49887
- return text6 && text6.length <= import_types5.OPEN_IN_TEXT_MAX ? text6 : null;
50284
+ const text6 = (0, import_types6.openInStartText)({ workspace: profile.workspace.slug, ticket: task.key, step, role, locale: lang, claim });
50285
+ return text6 && text6.length <= import_types6.OPEN_IN_TEXT_MAX ? text6 : null;
49888
50286
  }
49889
50287
  async function runStart(deps, input) {
49890
50288
  const { profile, task, root, program } = input;
@@ -49913,7 +50311,7 @@ async function runStart(deps, input) {
49913
50311
  let target = purpose === "work" ? existing[0] ?? null : null;
49914
50312
  if (purpose === "review") {
49915
50313
  try {
49916
- delivered = await deliveredBranch(deps, root, task.key);
50314
+ delivered = await deliveredBranch(deps, root, task.key, live.delivery);
49917
50315
  } catch (error) {
49918
50316
  target = existing.find((entry) => entry.terminal) ?? null;
49919
50317
  if (!target) throw error;
@@ -49949,7 +50347,7 @@ async function runStart(deps, input) {
49949
50347
  key: task.key,
49950
50348
  title: neutralizeLine(task.title).slice(0, 120),
49951
50349
  agent: agent === "codex" ? "Codex" : agent === "claude" ? "Claude" : neutralizeLine(agent).slice(0, 32),
49952
- task: (0, import_types5.openInTask)(step, role, cliLang)
50350
+ task: (0, import_types6.openInTask)(step, role, cliLang)
49953
50351
  };
49954
50352
  const state = delivered ? { branch: neutralizeLine(delivered.branch), sha: delivered.sha.slice(0, 10), date: delivered.date } : null;
49955
50353
  const question = [
@@ -53426,12 +53824,12 @@ async function validProgram(program, configDir) {
53426
53824
  }
53427
53825
 
53428
53826
  // src/link.ts
53429
- var import_types6 = __toESM(require_dist(), 1);
53827
+ var import_types7 = __toESM(require_dist(), 1);
53430
53828
  import { stat as stat13 } from "node:fs/promises";
53431
53829
  import { dirname as dirname17 } from "node:path";
53432
- var LINK_SCHEME = import_types6.OPEN_IN_LINK_SCHEME;
53830
+ var LINK_SCHEME = import_types7.OPEN_IN_LINK_SCHEME;
53433
53831
  function parseFleekLink(input) {
53434
- const link3 = (0, import_types6.parseOpenInLink)(input);
53832
+ const link3 = (0, import_types7.parseOpenInLink)(input);
53435
53833
  return link3 ? { action: "orca-open", ...link3 } : null;
53436
53834
  }
53437
53835
  var refused = (key, code, params = {}) => new CliError(key, EXIT.failed, params, code);
@@ -53964,7 +54362,7 @@ import { spawn as spawn7 } from "node:child_process";
53964
54362
  import { randomBytes as randomBytes10 } from "node:crypto";
53965
54363
  import { readFile as readFile21, realpath as realpath16 } from "node:fs/promises";
53966
54364
  import { isAbsolute as isAbsolute10, join as join28, resolve as resolve6, sep as sep8 } from "node:path";
53967
- var import_types7 = __toESM(require_dist(), 1);
54365
+ var import_types8 = __toESM(require_dist(), 1);
53968
54366
 
53969
54367
  // src/kit-keys.ts
53970
54368
  var KIT_KEYS = Object.freeze({
@@ -54042,7 +54440,7 @@ import { join as join26, resolve as resolve5 } from "node:path";
54042
54440
 
54043
54441
  // src/init-scan.ts
54044
54442
  import { spawn as spawn6 } from "node:child_process";
54045
- var import_validation = __toESM(require_dist2(), 1);
54443
+ var import_validation2 = __toESM(require_dist2(), 1);
54046
54444
  import { createHash as createHash7 } from "node:crypto";
54047
54445
  import { constants as fsConstants4 } from "node:fs";
54048
54446
  import { lstat as lstat12, mkdir as mkdir8, open as open5, realpath as realpath15, writeFile as writeFile4 } from "node:fs/promises";
@@ -54137,7 +54535,7 @@ async function readJson(root, path) {
54137
54535
  }
54138
54536
  async function readSmall2(root, path, max) {
54139
54537
  try {
54140
- if (!(0, import_validation.evidencePathAllowed)(path)) return null;
54538
+ if (!(0, import_validation2.evidencePathAllowed)(path)) return null;
54141
54539
  const realRoot = await realpath15(root), source = join25(root, path);
54142
54540
  if (await realpath15(source) !== join25(realRoot, ...path.split("/"))) return null;
54143
54541
  const seen = await lstat12(source);
@@ -54292,7 +54690,7 @@ async function scanFacts(checkout, app) {
54292
54690
  const stack = [];
54293
54691
  const add = (category, product, major, evidence) => {
54294
54692
  if (stack.some((entry) => entry.category === category && entry.product === product) || stack.length >= 60) return;
54295
- stack.push({ category, product, major, evidence: (0, import_validation.evidencePathAllowed)(evidence) ? [evidence] : [] });
54693
+ stack.push({ category, product, major, evidence: (0, import_validation2.evidencePathAllowed)(evidence) ? [evidence] : [] });
54296
54694
  };
54297
54695
  const manifestPath = `${prefix}package.json`;
54298
54696
  const manifest = own4.includes(manifestPath) ? await readJson(checkout.root, manifestPath) : null;
@@ -54339,9 +54737,9 @@ async function scanFacts(checkout, app) {
54339
54737
  }
54340
54738
  }
54341
54739
  const stories = own4.filter((file) => /\.stories\.(?:tsx?|jsx?|mdx|vue|svelte)$/.test(file));
54342
- const configPath = own4.find((file) => /(?:^|\/)\.storybook\/main\.(?:[cm]?[jt]s)$/.test(file) && (0, import_validation.evidencePathAllowed)(file)) ?? null;
54343
- const patternConfig = own4.find((file) => /(?:^|\/)patternlab-config\.json$/.test(file) && (0, import_validation.evidencePathAllowed)(file)) ?? null;
54344
- const patternFiles = own4.filter((file) => /(?:^|\/)source\/_patterns\/.*\.(?:mustache|twig|hbs|handlebars|html|njk)$/.test(file) && (0, import_validation.evidencePathAllowed)(file));
54740
+ const configPath = own4.find((file) => /(?:^|\/)\.storybook\/main\.(?:[cm]?[jt]s)$/.test(file) && (0, import_validation2.evidencePathAllowed)(file)) ?? null;
54741
+ const patternConfig = own4.find((file) => /(?:^|\/)patternlab-config\.json$/.test(file) && (0, import_validation2.evidencePathAllowed)(file)) ?? null;
54742
+ const patternFiles = own4.filter((file) => /(?:^|\/)source\/_patterns\/.*\.(?:mustache|twig|hbs|handlebars|html|njk)$/.test(file) && (0, import_validation2.evidencePathAllowed)(file));
54345
54743
  const hasPatternLabDependency = manifest !== null && Object.keys(dependencies(manifest)).some((name) => name.startsWith("@pattern-lab/"));
54346
54744
  const patternLab = patternConfig !== null || patternFiles.length > 0 || hasPatternLabDependency;
54347
54745
  const atomicLevel = (file) => file.match(/(?:^|\/)(?:\d+[-_])?(atoms|molecules|organisms|templates|pages)(?:\/|$)/)?.[1];
@@ -54358,24 +54756,24 @@ async function scanFacts(checkout, app) {
54358
54756
  return { name: name.slice(0, 120), ...parent && parent !== "." && parent !== name ? { group: parent.slice(0, 120) } : {}, path: file };
54359
54757
  }),
54360
54758
  ...patternFiles.slice(0, 200).map((file) => ({ name: posix3.basename(file).replace(/\.[^.]+$/, "").slice(0, 120), group: atomicLevel(file) ?? posix3.basename(posix3.dirname(file)), path: file }))
54361
- ].filter((c) => c.name && (0, import_validation.evidencePathAllowed)(c.path)).slice(0, 200);
54759
+ ].filter((c) => c.name && (0, import_validation2.evidencePathAllowed)(c.path)).slice(0, 200);
54362
54760
  const designSources = {};
54363
- const tokenPath = own4.find((file) => /(?:^|\/)(?:tokens\.json|style-dictionary(?:\.config)?\.[cm]?[jt]s|style-dictionary\.config\.json)$/.test(file) && (0, import_validation.evidencePathAllowed)(file));
54761
+ const tokenPath = own4.find((file) => /(?:^|\/)(?:tokens\.json|style-dictionary(?:\.config)?\.[cm]?[jt]s|style-dictionary\.config\.json)$/.test(file) && (0, import_validation2.evidencePathAllowed)(file));
54364
54762
  if (tokenPath) {
54365
54763
  designSources.tokens = { path: tokenPath, evidence: [tokenPath] };
54366
54764
  add("build", "design-tokens", null, tokenPath);
54367
54765
  }
54368
- const codeConnectPath = own4.find((file) => /(?:^|\/)figma\.config\.json$|\.figma\.[cm]?[jt]sx?$/.test(file) && (0, import_validation.evidencePathAllowed)(file));
54766
+ const codeConnectPath = own4.find((file) => /(?:^|\/)figma\.config\.json$|\.figma\.[cm]?[jt]sx?$/.test(file) && (0, import_validation2.evidencePathAllowed)(file));
54369
54767
  if (codeConnectPath) {
54370
54768
  designSources.codeConnect = { present: true, configPath: codeConnectPath };
54371
54769
  add("ui_library", "figma-code-connect", null, codeConnectPath);
54372
54770
  }
54373
- if (rootPath && patternFiles[0] && (0, import_validation.evidencePathAllowed)(rootPath)) designSources.components = { path: rootPath, evidence: [patternFiles[0]] };
54374
- const figmaSources = own4.filter((file) => /(?:^|\/)figma\.config\.json$|\.figma\.[cm]?[jt]sx?$/.test(file) && (0, import_validation.evidencePathAllowed)(file)).slice(0, 3);
54771
+ if (rootPath && patternFiles[0] && (0, import_validation2.evidencePathAllowed)(rootPath)) designSources.components = { path: rootPath, evidence: [patternFiles[0]] };
54772
+ const figmaSources = own4.filter((file) => /(?:^|\/)figma\.config\.json$|\.figma\.[cm]?[jt]sx?$/.test(file) && (0, import_validation2.evidencePathAllowed)(file)).slice(0, 3);
54375
54773
  for (const file of figmaSources) {
54376
54774
  const content3 = await readSmall2(checkout.root, file, INIT_SCAN_LIMITS.fileBytes);
54377
54775
  const url = content3?.match(/https:\/\/(?:www\.)?figma\.com\/(?:file|design)\/[A-Za-z0-9_-]+(?:\/[A-Za-z0-9_-]+)?/)?.[0];
54378
- if (url && (0, import_validation.environmentUrlAllowed)(url)) {
54776
+ if (url && (0, import_validation2.environmentUrlAllowed)(url)) {
54379
54777
  designSources.figmaFile = { url, evidence: [file] };
54380
54778
  break;
54381
54779
  }
@@ -54391,7 +54789,7 @@ async function scanFacts(checkout, app) {
54391
54789
  const inputs = checkout.files.filter((file) => !ignored(file) && (file.startsWith(prefix) && stagingAllowed(file.slice(prefix.length)) || !!prefix && rootInput(file)));
54392
54790
  const environmentNames = [];
54393
54791
  const environment = (name, file) => {
54394
- if (!/^[A-Za-z][A-Za-z0-9_-]{0,59}$/.test(name) || !(0, import_validation.evidencePathAllowed)(file) || environmentNames.length >= 30) return;
54792
+ if (!/^[A-Za-z][A-Za-z0-9_-]{0,59}$/.test(name) || !(0, import_validation2.evidencePathAllowed)(file) || environmentNames.length >= 30) return;
54395
54793
  const known = environmentNames.find((entry) => entry.name === name);
54396
54794
  if (known) {
54397
54795
  if (!known.evidence.includes(file) && known.evidence.length < 3) known.evidence.push(file);
@@ -54434,7 +54832,7 @@ async function scanFacts(checkout, app) {
54434
54832
  }
54435
54833
  const base = {
54436
54834
  stack,
54437
- storybook: { present: stories.length > 0 || configPath !== null, configPath: configPath && (0, import_validation.evidencePathAllowed)(configPath) ? configPath : null, stories: stories.length },
54835
+ storybook: { present: stories.length > 0 || configPath !== null, configPath: configPath && (0, import_validation2.evidencePathAllowed)(configPath) ? configPath : null, stories: stories.length },
54438
54836
  locales,
54439
54837
  ci,
54440
54838
  docker,
@@ -54442,7 +54840,7 @@ async function scanFacts(checkout, app) {
54442
54840
  ...Object.keys(designSources).length ? { designSources } : {},
54443
54841
  ...environmentNames.length ? { environmentNames } : {}
54444
54842
  };
54445
- const factsHash = createHash7("sha256").update((0, import_validation.projectInitCanonical)(base)).digest("hex");
54843
+ const factsHash = createHash7("sha256").update((0, import_validation2.projectInitCanonical)(base)).digest("hex");
54446
54844
  return { facts: { ...base, factsHash }, components };
54447
54845
  }
54448
54846
  var ENV_EXAMPLE = /^\.env\.(?:example|sample|template)$/;
@@ -54481,7 +54879,7 @@ function stagingAllowed(relative3) {
54481
54879
  if (segments.some((segment) => STAGING_DENY.test(segment))) return false;
54482
54880
  const name = posix3.basename(relative3);
54483
54881
  const checkedPath = ENV_EXAMPLE.test(name) ? [...segments.slice(0, -1), "env-example"].join("/") : relative3;
54484
- if (!(0, import_validation.evidencePathAllowed)(checkedPath)) return false;
54882
+ if (!(0, import_validation2.evidencePathAllowed)(checkedPath)) return false;
54485
54883
  if (/(?:^|[-.])lock(?:file)?(?:\.|$)|\.lock$|-lock\.|^yarn\.lock$|^pnpm-lock\.yaml$|^package-lock\.json$|^composer\.lock$|^Gemfile\.lock$|^go\.sum$/i.test(name)) return false;
54486
54884
  return ENV_EXAMPLE.test(name) || STAGING_ALLOW.some((pattern) => pattern.test(name)) || STAGING_ALLOW_PATH.some((pattern) => pattern.test(relative3));
54487
54885
  }
@@ -54566,7 +54964,7 @@ async function stageApplication(checkout, app, dir) {
54566
54964
  }
54567
54965
  const sourceBytes = bytes.length;
54568
54966
  if (envExample) bytes = Buffer.from(environmentKeys(bytes.toString("utf8")), "utf8");
54569
- if (designInputFile(file) && (0, import_validation.credentialShapeOf)(bytes.toString("utf8"))) {
54967
+ if (designInputFile(file) && (0, import_validation2.credentialShapeOf)(bytes.toString("utf8"))) {
54570
54968
  skipped++;
54571
54969
  continue;
54572
54970
  }
@@ -55717,7 +56115,7 @@ function parseListing(result) {
55717
56115
  const seen = /* @__PURE__ */ new Set();
55718
56116
  return kits.map((raw) => {
55719
56117
  const k = raw;
55720
- if (!k || typeof k !== "object" || !isKitKey(k.kitKey) || seen.has(k.kitKey) || !KIT_KINDS.includes(String(k.kind)) || !import_types7.PROJECT_MEMBER_ROLES.includes(String(k.role)) || !Number.isSafeInteger(k.version) || k.version < 1 || typeof k.versionId !== "string" || !UUID.test(k.versionId) || typeof k.contentHash !== "string" || !/^[0-9a-f]{64}$/.test(k.contentHash) || !KIT_PLACEMENTS.includes(String(k.placement)) || !Number.isSafeInteger(k.parts) || k.parts < 1 || k.parts > KIT_MAX_PARTS) {
56118
+ if (!k || typeof k !== "object" || !isKitKey(k.kitKey) || seen.has(k.kitKey) || !KIT_KINDS.includes(String(k.kind)) || !import_types8.PROJECT_MEMBER_ROLES.includes(String(k.role)) || !Number.isSafeInteger(k.version) || k.version < 1 || typeof k.versionId !== "string" || !UUID.test(k.versionId) || typeof k.contentHash !== "string" || !/^[0-9a-f]{64}$/.test(k.contentHash) || !KIT_PLACEMENTS.includes(String(k.placement)) || !Number.isSafeInteger(k.parts) || k.parts < 1 || k.parts > KIT_MAX_PARTS) {
55721
56119
  throw protocol("listing");
55722
56120
  }
55723
56121
  seen.add(k.kitKey);
@@ -56755,7 +57153,7 @@ async function kitRun(ctx, client, values, userArgs) {
56755
57153
 
56756
57154
  // src/init.ts
56757
57155
  import { createHash as createHash8, randomUUID as randomUUID4 } from "node:crypto";
56758
- var import_validation2 = __toESM(require_dist2(), 1);
57156
+ var import_validation3 = __toESM(require_dist2(), 1);
56759
57157
  import { constants as fsConstants5 } from "node:fs";
56760
57158
  import { lstat as lstat13, mkdir as mkdir10, mkdtemp as mkdtemp2, open as open6, readdir as readdir12, realpath as realpath17, rename as rename4, rm as rm11, writeFile as writeFile6 } from "node:fs/promises";
56761
57159
  import { tmpdir } from "node:os";
@@ -56846,11 +57244,11 @@ function instructions2(ctx, app, facts) {
56846
57244
  "",
56847
57245
  ...projectFactLines(de, facts),
56848
57246
  de ? "## Ausgabe" : "## Output",
56849
- de ? `Liefere genau ein JSON-Objekt: beim gedruckten manuellen Befehl nur JSON auf stdout (der Befehl schreibt atomar), sonst genau eine JSON-Datei \`agent-output.json\` im Ausgabeverzeichnis (erst \`.tmp\`, dann umbenennen), Format \`${import_validation2.PROJECT_INIT_AGENT_FORMAT}\`:` : `Return exactly one JSON object: with the printed manual command, only JSON on stdout (the command writes atomically), otherwise exactly one JSON file \`agent-output.json\` in the output directory (write \`.tmp\` first, then rename), format \`${import_validation2.PROJECT_INIT_AGENT_FORMAT}\`:`,
57247
+ de ? `Liefere genau ein JSON-Objekt: beim gedruckten manuellen Befehl nur JSON auf stdout (der Befehl schreibt atomar), sonst genau eine JSON-Datei \`agent-output.json\` im Ausgabeverzeichnis (erst \`.tmp\`, dann umbenennen), Format \`${import_validation3.PROJECT_INIT_AGENT_FORMAT}\`:` : `Return exactly one JSON object: with the printed manual command, only JSON on stdout (the command writes atomically), otherwise exactly one JSON file \`agent-output.json\` in the output directory (write \`.tmp\` first, then rename), format \`${import_validation3.PROJECT_INIT_AGENT_FORMAT}\`:`,
56850
57248
  "",
56851
57249
  "```json",
56852
57250
  JSON.stringify({
56853
- format: import_validation2.PROJECT_INIT_AGENT_FORMAT,
57251
+ format: import_validation3.PROJECT_INIT_AGENT_FORMAT,
56854
57252
  sections: { overview: "…", architecture: "…", componentsNote: "…", cmsNote: "…", integrationsNote: "…" },
56855
57253
  components: [{ name: "Button", group: "Basis", note: "…" }],
56856
57254
  cms: null,
@@ -56863,7 +57261,7 @@ function instructions2(ctx, app, facts) {
56863
57261
  }, null, 2),
56864
57262
  "```",
56865
57263
  "",
56866
- de ? `Grenzen: Abschnitte ≤ ${import_validation2.PROJECT_INIT_LIMITS.section} Zeichen, Hinweise ≤ ${import_validation2.PROJECT_INIT_LIMITS.reviewHints}, Datei ≤ 64 KiB. Einfacher Text mit Absätzen und Spiegelstrichen.` : `Bounds: sections <= ${import_validation2.PROJECT_INIT_LIMITS.section} characters, hints <= ${import_validation2.PROJECT_INIT_LIMITS.reviewHints}, file <= 64 KiB. Plain text with paragraphs and bullets.`
57264
+ 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.`
56867
57265
  ].join("\n");
56868
57266
  }
56869
57267
  function projectFactLines(de, facts) {
@@ -56952,7 +57350,7 @@ async function startAgent(ctx, values, stagingDir, outputFile, timeoutMs, app) {
56952
57350
  env,
56953
57351
  signal: ctx.deps.signal,
56954
57352
  timeoutMs: Math.max(1, timeoutMs),
56955
- maxBytes: import_validation2.PROJECT_INIT_LIMITS.summaryBytes
57353
+ maxBytes: import_validation3.PROJECT_INIT_LIMITS.summaryBytes
56956
57354
  }));
56957
57355
  if (result.code !== 0) throw new CliError("errors.initAgentFailed", EXIT.failed, { code: result.code }, "AGENT_FAILED");
56958
57356
  const temporary = `${outputFile}.tmp`;
@@ -57080,7 +57478,7 @@ async function initCommand(ctx, values) {
57080
57478
  if (!apps.includes(app)) apps.push(app);
57081
57479
  }
57082
57480
  } else if (tty) {
57083
- const max = import_validation2.PROJECT_INIT_LIMITS.applicationsPerRun;
57481
+ const max = import_validation3.PROJECT_INIT_LIMITS.applicationsPerRun;
57084
57482
  const defaults = candidates.filter((app) => !app.library).slice(0, max);
57085
57483
  const lines = [
57086
57484
  ctx.t("init.selectHeading", { count: candidates.length, max }),
@@ -57103,7 +57501,7 @@ async function initCommand(ctx, values) {
57103
57501
  if (picked === null) throw usage3("errors.initSelection", { max, project: values.project, app: candidates[0]?.key ?? "app" });
57104
57502
  apps = picked;
57105
57503
  } else throw usage3("errors.initYesNeedsApp");
57106
- if (apps.length > import_validation2.PROJECT_INIT_LIMITS.applicationsPerRun) throw usage3("errors.initTooManyApps", { max: import_validation2.PROJECT_INIT_LIMITS.applicationsPerRun });
57504
+ if (apps.length > import_validation3.PROJECT_INIT_LIMITS.applicationsPerRun) throw usage3("errors.initTooManyApps", { max: import_validation3.PROJECT_INIT_LIMITS.applicationsPerRun });
57107
57505
  if (!apps.length) throw usage3("errors.initNoApps");
57108
57506
  const existing = context.applications.filter((entry) => entry.name !== null && APPLICATION_KEY.test(entry.key));
57109
57507
  const mapping = await mapApplications(ctx, apps, explicit, existing, tty && !values.yes, values.verbose);
@@ -57250,20 +57648,20 @@ async function runApplication(ctx, client, values, checkout, context, app, appli
57250
57648
  const staged = await stageApplication(checkout, app, stagingDir);
57251
57649
  const applicationKey = application.key;
57252
57650
  const input = {
57253
- format: import_validation2.PROJECT_INIT_INPUT_FORMAT,
57651
+ format: import_validation3.PROJECT_INIT_INPUT_FORMAT,
57254
57652
  application: { key: applicationKey, name: application.name, path: app.path, kind: app.kind },
57255
57653
  facts,
57256
57654
  files: staged.files,
57257
57655
  base: known?.base ?? null,
57258
57656
  statements: Array.isArray(known?.statements) ? known.statements.slice(0, 100) : [],
57259
- outputFormat: import_validation2.PROJECT_INIT_AGENT_FORMAT
57657
+ outputFormat: import_validation3.PROJECT_INIT_AGENT_FORMAT
57260
57658
  };
57261
57659
  const inputFile = join29(stagingDir, "fleek-input.json"), instructionsFile = join29(stagingDir, "FLEEK-INIT.md"), outputFile = join29(outputDir, "agent-output.json");
57262
57660
  await writeFile6(inputFile, `${JSON.stringify(input, null, 2)}
57263
57661
  `, { mode: 256 });
57264
57662
  await writeFile6(instructionsFile, `${instructions2(ctx, app, facts)}
57265
57663
  `, { mode: 256 });
57266
- const stagingDigest = createHash8("sha256").update(JSON.stringify([import_validation2.PROJECT_INIT_FORMAT, INIT_CLI_VERSION, staged.digest, facts.factsHash, input.base, input.statements])).digest("hex");
57664
+ const stagingDigest = createHash8("sha256").update(JSON.stringify([import_validation3.PROJECT_INIT_FORMAT, INIT_CLI_VERSION, staged.digest, facts.factsHash, input.base, input.statements])).digest("hex");
57267
57665
  const idempotencyKey = values.yes ? `pi-${createHash8("sha256").update(JSON.stringify([context.project.teamId, applicationKey, checkout.commit, stagingDigest])).digest("hex")}` : `pi-${createHash8("sha256").update(`${runId}:${app.key}`).digest("hex")}`;
57268
57666
  if (values.yes && !values["dry-run"] && (await client.availableTools()).has(ACTION_STATUS_TOOL)) {
57269
57667
  const status = await client.callTool(ACTION_STATUS_TOOL, { action: WIRE.projectInitSubmit, idempotencyKey }).then((r) => r.structured).catch(() => null);
@@ -57302,18 +57700,18 @@ async function runApplication(ctx, client, values, checkout, context, app, appli
57302
57700
  let raw;
57303
57701
  try {
57304
57702
  const seen = await lstat13(outputFile);
57305
- if (!seen.isFile() || seen.nlink !== 1 || seen.size > import_validation2.PROJECT_INIT_LIMITS.summaryBytes) throw new Error("not a bounded file");
57703
+ if (!seen.isFile() || seen.nlink !== 1 || seen.size > import_validation3.PROJECT_INIT_LIMITS.summaryBytes) throw new Error("not a bounded file");
57306
57704
  const handle = await open6(outputFile, fsConstants5.O_RDONLY | (fsConstants5.O_NOFOLLOW ?? 0) | (fsConstants5.O_NONBLOCK ?? 0));
57307
57705
  try {
57308
57706
  const info = await handle.stat();
57309
57707
  if (!info.isFile() || info.ino !== seen.ino || info.dev !== seen.dev || info.nlink !== 1) throw new Error("replaced");
57310
- const buffer = Buffer.alloc(import_validation2.PROJECT_INIT_LIMITS.summaryBytes + 1);
57708
+ const buffer = Buffer.alloc(import_validation3.PROJECT_INIT_LIMITS.summaryBytes + 1);
57311
57709
  let length = 0;
57312
57710
  for (; ; ) {
57313
57711
  const { bytesRead } = await handle.read(buffer, length, buffer.length - length, length);
57314
57712
  if (bytesRead === 0) break;
57315
57713
  length += bytesRead;
57316
- if (length > import_validation2.PROJECT_INIT_LIMITS.summaryBytes) throw new Error("too large");
57714
+ if (length > import_validation3.PROJECT_INIT_LIMITS.summaryBytes) throw new Error("too large");
57317
57715
  }
57318
57716
  raw = JSON.parse(buffer.subarray(0, length).toString("utf8"));
57319
57717
  } finally {
@@ -57322,33 +57720,33 @@ async function runApplication(ctx, client, values, checkout, context, app, appli
57322
57720
  } catch {
57323
57721
  raw = void 0;
57324
57722
  }
57325
- const agentOutput = raw === void 0 ? null : (0, import_validation2.parseProjectInitAgentOutput)(raw);
57723
+ const agentOutput = raw === void 0 ? null : (0, import_validation3.parseProjectInitAgentOutput)(raw);
57326
57724
  if (!agentOutput?.ok) {
57327
57725
  emit(ctx, { event: "error", app: app.key, code: "output_invalid" });
57328
57726
  if (!ctx.json) ctx.out.error(ctx.out.style.fail(ctx.t("init.outputInvalid", { app: app.key, field: agentOutput && !agentOutput.ok ? agentOutput.issues[0]?.path || "-" : "-" })));
57329
57727
  return "failed";
57330
57728
  }
57331
- const composed = (0, import_validation2.composeProjectInitSummary)({
57729
+ const composed = (0, import_validation3.composeProjectInitSummary)({
57332
57730
  application: { key: applicationKey, name: application.name, path: app.path, kind: app.kind },
57333
57731
  source: { commit: checkout.commit, dirty: checkout.dirty, analyzedAt: new Date(ctx.now()).toISOString(), cliVersion: INIT_CLI_VERSION, kitVersion: null, agent: started ? "claude_code" : "manual" },
57334
57732
  facts,
57335
57733
  components
57336
57734
  }, agentOutput.value, input.statements);
57337
- const parsed = (0, import_validation2.parseProjectInitSummary)(composed);
57735
+ const parsed = (0, import_validation3.parseProjectInitSummary)(composed);
57338
57736
  if (!parsed.ok) {
57339
57737
  emit(ctx, { event: "error", app: app.key, code: "output_invalid" });
57340
57738
  if (!ctx.json) ctx.out.error(ctx.out.style.fail(ctx.t("init.outputInvalid", { app: app.key, field: parsed.issues[0]?.path || "-" })));
57341
57739
  return "failed";
57342
57740
  }
57343
- const findings = (0, import_validation2.scanProjectInit)(parsed.value);
57344
- const summary = (0, import_validation2.stripProjectInitFindings)(parsed.value, findings);
57741
+ const findings = (0, import_validation3.scanProjectInit)(parsed.value);
57742
+ const summary = (0, import_validation3.stripProjectInitFindings)(parsed.value, findings);
57345
57743
  const removed = findings.map((finding) => ({ path: finding.path, reason: finding.reason }));
57346
57744
  if (!summary) {
57347
57745
  emit(ctx, { event: "error", app: app.key, code: "application_unusable" });
57348
57746
  if (!ctx.json) ctx.out.error(ctx.out.style.fail(ctx.t("init.unusable", { app: app.key })));
57349
57747
  return "failed";
57350
57748
  }
57351
- const warnings = (0, import_validation2.projectInitWarnings)(summary).length;
57749
+ const warnings = (0, import_validation3.projectInitWarnings)(summary).length;
57352
57750
  emit(ctx, { event: "checked", app: app.key, removed, warnings });
57353
57751
  if (!ctx.json) {
57354
57752
  const s = ctx.out.style;
@@ -57400,7 +57798,7 @@ async function runApplication(ctx, client, values, checkout, context, app, appli
57400
57798
  }
57401
57799
 
57402
57800
  // src/service.ts
57403
- var import_types8 = __toESM(require_dist(), 1);
57801
+ var import_types9 = __toESM(require_dist(), 1);
57404
57802
  import { spawn as spawn8 } from "node:child_process";
57405
57803
  import { randomBytes as randomBytes11, randomUUID as randomUUID5 } from "node:crypto";
57406
57804
  import { constants as fsConstants6 } from "node:fs";
@@ -57502,7 +57900,7 @@ var TokenFilter = class {
57502
57900
  var usage4 = () => new CliError("errors.usage", EXIT.usage, {}, "USAGE");
57503
57901
  function normalizeSetupCode(value) {
57504
57902
  const code = (value ?? "").toUpperCase().replace(/[\s-]/g, "");
57505
- if (code.length !== import_types8.SERVICE_ACCOUNT_USER_CODE_LENGTH || [...code].some((char) => !import_types8.SERVICE_ACCOUNT_USER_CODE_CHARSET.includes(char))) throw usage4();
57903
+ if (code.length !== import_types9.SERVICE_ACCOUNT_USER_CODE_LENGTH || [...code].some((char) => !import_types9.SERVICE_ACCOUNT_USER_CODE_CHARSET.includes(char))) throw usage4();
57506
57904
  return code;
57507
57905
  }
57508
57906
  function serverArg(value) {
@@ -58386,7 +58784,7 @@ function realSystem(options = {}) {
58386
58784
  }
58387
58785
 
58388
58786
  // src/setup.ts
58389
- var import_types9 = __toESM(require_dist(), 1);
58787
+ var import_types10 = __toESM(require_dist(), 1);
58390
58788
  import { hostname } from "node:os";
58391
58789
  import { join as join32, resolve as resolve8 } from "node:path";
58392
58790
  import { realpath as realpath19 } from "node:fs/promises";
@@ -58549,7 +58947,7 @@ function createSetupProxyAdapter(ctx) {
58549
58947
  // src/setup.ts
58550
58948
  async function setupCommand(ctx, code, values) {
58551
58949
  const normalized = (code ?? "").replace(/-/g, "").toUpperCase();
58552
- if (normalized.length !== 8 || [...normalized].some((char) => !import_types9.SERVICE_ACCOUNT_USER_CODE_CHARSET.includes(char))) {
58950
+ if (normalized.length !== 8 || [...normalized].some((char) => !import_types10.SERVICE_ACCOUNT_USER_CODE_CHARSET.includes(char))) {
58553
58951
  throw new CliError("errors.setupCode", EXIT.usage, {}, "INVALID_SETUP_CODE");
58554
58952
  }
58555
58953
  registerSecret(code);
@@ -59225,7 +59623,7 @@ function derivedClientId(origin) {
59225
59623
  const url = new URL(origin);
59226
59624
  const labels = url.hostname.split(".");
59227
59625
  if (url.protocol !== "https:" || labels.length < 3) return null;
59228
- return (0, import_types10.fleekCliClientId)(`https://app.${labels.slice(1).join(".")}`);
59626
+ return (0, import_types11.fleekCliClientId)(`https://app.${labels.slice(1).join(".")}`);
59229
59627
  }
59230
59628
  function validClientId(value) {
59231
59629
  let url;
@@ -59425,7 +59823,7 @@ async function login(ctx, values, guided = false) {
59425
59823
  throw new CliError(pending.expiresAt <= ctx.now() ? "errors.setupDeviceExpired" : "errors.setupDeviceRestart", EXIT.needsLogin, {}, "EXPIRED_TOKEN");
59426
59824
  }
59427
59825
  registerSecret(pending.accessToken);
59428
- const uri = `${(0, import_types10.serviceDeviceVerificationOrigin)(info.issuer)}/device`;
59826
+ const uri = `${(0, import_types11.serviceDeviceVerificationOrigin)(info.issuer)}/device`;
59429
59827
  device = {
59430
59828
  deviceCode: pending.accessToken,
59431
59829
  userCode: saved.userCode,
@@ -59710,7 +60108,7 @@ async function work(ctx, sub, args, values) {
59710
60108
  WIRE.claim,
59711
60109
  {
59712
60110
  issueId: id,
59713
- purpose: oneOf2(values.purpose, import_types10.CLAIM_PURPOSES) ?? "work",
60111
+ purpose: oneOf2(values.purpose, import_types11.CLAIM_PURPOSES) ?? "work",
59714
60112
  ...values.ttl ? { ttlMinutes: int(values.ttl, 1, 1440) } : {},
59715
60113
  ...values.note ? { note: text5(values.note, 280) } : {}
59716
60114
  },
@@ -59729,7 +60127,7 @@ async function work(ctx, sub, args, values) {
59729
60127
  );
59730
60128
  case "release":
59731
60129
  case "complete": {
59732
- const outcome = sub === "release" ? oneOf2(values.outcome, import_types10.CLAIM_RELEASE_OUTCOMES, true) : oneOf2(values.outcome, import_types10.CLAIM_COMPLETE_OUTCOMES, true);
60130
+ const outcome = sub === "release" ? oneOf2(values.outcome, import_types11.CLAIM_RELEASE_OUTCOMES, true) : oneOf2(values.outcome, import_types11.CLAIM_COMPLETE_OUTCOMES, true);
59733
60131
  return write(
59734
60132
  ctx,
59735
60133
  client,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logic-joe/fleek",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "fleek - command line client for the Fleek agent hub (MCP over OAuth, OS keychain, signed role/project kits)",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",