@nullplatform/mcp 0.1.1 → 0.1.3

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.
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: configuring-safely
3
+ description: Use when setting, changing, or rotating an application's parameters or secrets (env vars / files) on nullplatform — what is safe, what only takes effect on the next deploy, and how to rotate without downtime.
4
+ ---
5
+
6
+ # Configuring safely on nullplatform
7
+
8
+ A parameter change is **inert until you redeploy**. Setting it is half the job; the value
9
+ reaches running instances only when each scope that uses it deploys again. Secret values are
10
+ encrypted and shown masked — but they are versioned, not write-once.
11
+
12
+ ## What a parameter is
13
+
14
+ - An environment variable or a file (`type:"ENVIRONMENT"|"FILE"`), defined on the application
15
+ and resolved per scope at deploy time. Mark credentials `secret:true`.
16
+ - `application_parameter_create` is an upsert and convergent: re-running with the same name
17
+ changes the value (it reports created vs updated) and never duplicates. Each change is kept
18
+ as a new version platform-side (history lives in the dashboard).
19
+ - Secret values are masked in `application_parameter_list` and in tool output. Revealing the
20
+ real value needs the `parameter:read-secrets` permission (often itself approval-gated) and is
21
+ done in the dashboard — this integration never prints a secret back.
22
+
23
+ ## Setting a value
24
+
25
+ 1. Treat the repo as the source of truth for what the value should be — a local `.env` or config
26
+ file is the usual reference. Never paste a secret's value into chat, a commit, or a log.
27
+ 2. `application_parameter_create` writes the **application-level** value. Per-scope and
28
+ per-dimension overrides (a different value in production) are managed in the dashboard. So if
29
+ a value seems not to take effect, a more specific override may be shadowing it — the effective
30
+ value is the most specific: scope override → dimension match → application default.
31
+
32
+ ## Making it live (the step that's easy to forget)
33
+
34
+ 3. Nothing changes until each scope redeploys. List the scopes with `application_get` and
35
+ redeploy every one that should pick the value up — metric-gated, per `deploying-safely`.
36
+ Reporting "parameter updated" without the pending redeploy is misleading.
37
+
38
+ ## Rotating a secret
39
+
40
+ 4. There is no in-place rotate. Set the new value (`application_parameter_create`, same name) →
41
+ redeploy **every** scope that uses it → verify each is healthy → only then revoke the old
42
+ credential upstream. Order matters: a scope left un-redeployed is still serving the old value,
43
+ and revoking it first breaks that scope.
44
+
45
+ ## Gotchas & don'ts
46
+
47
+ - A parameter's `type`, `name`, and `secret` flag are fixed once created. To change those, create
48
+ a new parameter and remove the old one (then redeploy).
49
+ - Don't echo a secret value anywhere. Don't treat a value as live before the redeploy. Don't
50
+ assume the application-level value is what production serves — check for a scope override first.
@@ -16,6 +16,8 @@ over in steps you control, and nothing is destroyed until you finalize. Rollback
16
16
  rejects overlapping deploys).
17
17
  - What will ship: if the latest successful build is newer than the latest release,
18
18
  `application_deployment_create` will cut the release automatically — say so before doing it.
19
+ Running in the repo, read `git log` / the diff since the live release's commit to tell the
20
+ user what this deploy actually changes.
19
21
  - The target scope: when several exist, pick by dimension (`scope:"environment=production"`),
20
22
  never by guessing. Production-dimension scopes deserve a confirmation from the user.
21
23
  2. If the change involved parameters (`application_parameter_create`), remember values only apply on this
@@ -30,7 +32,7 @@ over in steps you control, and nothing is destroyed until you finalize. Rollback
30
32
  (dashboard → Approvals). Don't retry; watch with `application_get deployment:<id>`.
31
33
  2. Wait for `running` (instances healthy). `waiting_for_instances` lasting more than ~5
32
34
  minutes usually means a failing health check — check `application_log_list` before pushing traffic.
33
- 3. Walk traffic in steps — allowed marks are 1, 5, 10, 25, 50, 75, 90, 95, 99, 100:
35
+ 3. Walk traffic in steps — allowed marks are 0, 1, 5, 10, 25, 50, 75, 90, 95, 99, 100:
34
36
  - Low-risk/dev: 25 → 100 is fine.
35
37
  - Production: 5 or 10 → 25 → 50 → 100, pausing 2–5 minutes per step.
36
38
  4. **Gate every step on metrics** (`application_metric_list`, 1h window, compare against pre-deploy):
@@ -50,5 +52,6 @@ Prefer a needless rollback over a defended bad deploy. After rolling back, captu
50
52
  ## First-ever deploy on a scope
51
53
 
52
54
  There is no old version to fall back to: traffic semantics don't apply, the deployment
53
- finalizes on its own once instances are healthy, and "rollback" means cancel. Verify with
54
- the scope's domain URL from `application_get` once finalized.
55
+ finalizes on its own once instances are healthy, and "rollback" means cancel which ends in
56
+ `failed`, leaving the scope to be recreated rather than reverted. Verify with the scope's
57
+ domain URL from `application_get` once finalized.
@@ -34,6 +34,8 @@ to the last known-good version.
34
34
  - throughput cliff to ~0 → upstream/routing problem; the app may be healthy.
35
35
  - `application_log_list` (the affected scope; filter for `ERROR`, `FATAL`, stack traces):
36
36
  - note the FIRST error timestamp and correlate with the deploy time from `application_get`.
37
+ - running in the repo: map the suspect release to its build commit and read `git log` around
38
+ it — the changes between the last-good and the current release are the prime suspects.
37
39
  - `application_parameter_list` — config is a top cause: was a parameter changed before the last deploy?
38
40
  Secret values are masked, but names + the deploy timing tell the story.
39
41
 
@@ -47,6 +49,7 @@ and the evidence — and leave the bad release identified so it isn't redeployed
47
49
  ## Don'ts
48
50
 
49
51
  - Don't deploy a "quick fix" forward while the incident is open — roll back first.
50
- - Don't finalize anything during an incident.
52
+ - Don't finalize during an incident — once a deploy is `finalizing` it can't be cancelled or
53
+ rolled back; it only retries forward.
51
54
  - Don't restart/recreate scopes as a first move; that destroys the evidence and rarely
52
55
  fixes the cause.
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: managing-environments
3
+ description: Use when adding or changing a nullplatform deploy target (scope / environment / region) — identifying existing scopes, carrying the org's dimensions, and the first deploy to a fresh scope.
4
+ ---
5
+
6
+ # Managing environments on nullplatform
7
+
8
+ A scope IS an environment, and creating one **provisions real infrastructure asynchronously**.
9
+ Identify before you create, carry the org's dimensions, and mirror a sibling.
10
+
11
+ ## 1. Identify before creating
12
+
13
+ `application_get` first — list the existing scopes and their dimensions. "Add staging" often
14
+ means a scope that already exists; match by **dimension** (`environment=staging`), not by display
15
+ name. `application_scope_create` is convergent (an existing name returns that scope), but a
16
+ near-duplicate under a different name is a real-infrastructure mistake.
17
+
18
+ ## 2. Dimensions
19
+
20
+ In orgs that use runtime dimensions a new scope must carry them (e.g. `environment`, `country`).
21
+ `application_scope_create` borrows the shape of an existing scope when you don't pass
22
+ `dimensions` — usually what you want. Set them right at creation: the dashboard locks dimensions
23
+ afterwards, so treat them as fixed even though the platform technically allows edits. A
24
+ production-dimension scope deserves an explicit confirmation from the user.
25
+
26
+ ## 3. Create
27
+
28
+ `application_scope_create name:"…"` (it lists the scope types to choose from if the org has
29
+ several). It returns immediately with the scope **provisioning** — the infrastructure comes up
30
+ out of band. Poll with `application_get` until it's active before deploying; the create response
31
+ is accepted intent, not a ready environment.
32
+
33
+ ## 4. Mirror config, then first deploy
34
+
35
+ - A new environment with missing parameters will misbehave. Bring the sibling's configuration
36
+ across (`application_parameter_create`, per `configuring-safely`) before the first deploy.
37
+ - The first deploy to a fresh scope is special: there's no previous version, so traffic-splitting
38
+ doesn't apply — it finalizes on its own once instances are healthy, and a cancel ends in
39
+ `failed` (the scope must be recreated, since there's nothing to fall back to). Verify via the
40
+ scope's domain URL from `application_get`.
41
+
42
+ ## Sizing & later edits
43
+
44
+ Sizing/capabilities and post-creation dimension edits aren't exposed by this integration — set
45
+ what you can at creation and deep-link to the dashboard for the rest. An under-sized scope shows
46
+ up later as CPU/memory near limits in `application_metric_list`.
47
+
48
+ ## Don'ts
49
+
50
+ - Don't create a duplicate of an existing scope; identify first.
51
+ - Don't guess dimension values — borrow a sibling's (the tool does this by default).
52
+ - Don't treat scope creation as cheap or instant: it's real infrastructure, provisioned
53
+ asynchronously.
@@ -30,29 +30,39 @@ Scopes carry org-defined dimensions like `environment` and `country`
30
30
 
31
31
  ## Versioning
32
32
 
33
- - Releases use semver, optionally `v`-prefixed; orgs may enforce a pattern.
34
- - Auto-cut releases bump the patch. "Deploy 1.4.0" targets the EXISTING 1.4.0 release —
33
+ - Releases use semver, optionally `v`-prefixed; an org may enforce a pattern
34
+ (`settings.releases.versionPattern`). Whoever cuts the release chooses the semver.
35
+ - When a tool cuts a release for you (deploy, `application_release_create`) it defaults to
36
+ bumping the patch of the latest release. "Deploy 1.4.0" targets the EXISTING 1.4.0 release —
35
37
  that's also how you roll back after a finalize.
36
38
 
37
39
  ## Parameters
38
40
 
39
- - Env vars or files, app-NRN scoped, optionally secret (values never readable again).
41
+ - Env vars or files, app-NRN scoped, optionally secret. Secret values are masked by default;
42
+ reading the real value needs the `parameter:read-secrets` permission (often itself
43
+ approval-gated) and is not exposed by this integration — a value is versioned, not write-once.
40
44
  - Changes take effect ONLY on the next deploy of each scope — saying "parameter updated"
41
45
  without mentioning the pending redeploy is misleading.
46
+ - The effective value for a scope is the most specific one: scope override → dimension match →
47
+ application default.
42
48
 
43
49
  ## Traffic & lifecycle semantics
44
50
 
45
- - Traffic percentages snap to: 1, 5, 10, 25, 50, 75, 90, 95, 99, 100.
51
+ - Traffic percentages snap to: 0, 1, 5, 10, 25, 50, 75, 90, 95, 99, 100 (0 drains the new version).
46
52
  - Deployment statuses: `creating → waiting_for_instances → running (traffic phase) →
47
- finalizing → finalized`; terminal also includes `failed`, `cancelled`, `rolled_back`,
48
- `creating_approval_denied`. `creating_approval` means a human approval gate.
53
+ finalizing → finalized`; a rollback runs `cancelling rolling_back → rolled_back`; terminal
54
+ also includes `failed`. `creating_approval` means a human approval gate (denied →
55
+ `creating_approval_denied`). A separate axis, `statusInScope` (active/candidate/inactive),
56
+ is what the scope actually serves. Once a deploy is `finalizing` it can't be cancelled — it
57
+ only retries forward.
49
58
  - One active rollout per scope.
50
59
 
51
60
  ## Gotchas worth knowing
52
61
 
53
- - Multi-asset builds (e.g. docker + lambda) need an asset choice per scope; the platform's
54
- error for a wrong/missing choice misleadingly says "scope and release belong to
55
- different applications".
62
+ - Multi-asset builds (e.g. docker + lambda) need an asset choice per scope (set the scope's
63
+ asset when a build emits more than one; a single-asset build needs no choice). A wrong or
64
+ missing choice is rejected with a misleading "scope and release belong to different
65
+ applications" — it actually means "pick the asset" (a real runtime error, verified live).
56
66
  - Logs and metrics are per-scope, never app-wide.
57
67
  - Approvals can gate deploys org-wide; a "stuck" deploy in `creating_approval` is waiting
58
68
  for a human, not broken.
@@ -0,0 +1,51 @@
1
+ ---
2
+ name: promoting-across-environments
3
+ description: Use when moving a validated release from one environment to the next (dev → staging → production) on nullplatform, or when two environments behave differently — promote the same release, and tell release drift from config drift.
4
+ ---
5
+
6
+ # Promoting across environments on nullplatform
7
+
8
+ Build once, deploy the same release everywhere. A release is an immutable, application-wide
9
+ pointer to a build, so promoting to the next environment means **deploying the release you
10
+ already validated** onto that environment's scope — never rebuilding, never cutting a new release
11
+ per environment. What you tested is then exactly what ships.
12
+
13
+ > "Promote" here is the developer sense: move a release to the next environment. The platform
14
+ > also uses "promote" for *finalize* — promoting a deployment's candidate over the old version
15
+ > within one rollout. Different operation; don't conflate them.
16
+
17
+ ## Promoting a release
18
+
19
+ 1. Validate on the lower environment first. With `application_get`, confirm which release is live
20
+ on (say) the `environment=staging` scope and that it's healthy — metrics and logs per
21
+ `deploying-safely`.
22
+ 2. Deploy that **same** release to the next scope by version:
23
+ `application_deployment_create version:"1.4.2" scope:"environment=production"`. Passing the
24
+ existing version deploys it as-is; it does not cut a new release. Do NOT deploy "latest" here —
25
+ a newer build may exist between staging and prod, and "latest" would ship something you never
26
+ validated.
27
+ 3. Walk traffic and gate exactly as in `deploying-safely`. A production-dimension scope deserves
28
+ an explicit confirmation. Repeat environment by environment.
29
+
30
+ ## When an environment behaves differently (drift)
31
+
32
+ Two scopes running "the same app" can differ in exactly two ways — establish which before acting:
33
+
34
+ - **Release drift** — they're on different releases. `application_get` shows the live release per
35
+ scope; staging on 1.4.2 and prod on 1.3.0 is the whole story. The fix is promotion (above), not
36
+ debugging.
37
+ - **Config drift** — same release, different configuration. A parameter can be overridden per
38
+ scope or dimension (effective value: scope → dimension → application), so prod may resolve a
39
+ different value than staging. `application_parameter_list` shows the names; per-scope override
40
+ values live in the dashboard. Fuse with the repo — a local `.env` or config file is the
41
+ reference for what each environment *should* carry.
42
+
43
+ Promoting a release won't fix a config difference, and changing config won't close a release gap —
44
+ so name the drift before you touch anything.
45
+
46
+ ## Don'ts
47
+
48
+ - Don't rebuild per environment, and don't cut a separate release for prod — promote the one you
49
+ validated.
50
+ - Don't deploy "latest" to production when you mean "the release that passed staging".
51
+ - Don't assume parity: two scopes can drift on release, on config, or both.
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: tracing-a-change
3
+ description: Use to answer "is this ticket / PR / commit live, and where?" on nullplatform — walk a commit from the issue key to the scopes serving it.
4
+ ---
5
+
6
+ # Tracing a change on nullplatform
7
+
8
+ Intent and delivery join on the **commit**. Given a ticket, a PR, or a commit, walk it forward to
9
+ the environments actually serving it — and be precise about the gap, because *merged* is not
10
+ *deployed*.
11
+
12
+ ## The walk
13
+
14
+ 1. **Work item → commit.** Get the commit SHA the change landed in: from the issue's linked PR in
15
+ the tracker, or in the repo with `git log --grep="PROJ-123"` (the issue key on the commit). Use
16
+ the full SHA.
17
+ 2. **Commit → build.** `application_build_list commit:"<sha>"` returns the build(s) for that exact
18
+ commit (a build records its commit). No build → it hasn't built yet, or the commit isn't on a
19
+ built branch.
20
+ 3. **Build → release.** A build ships only once someone has cut a release from it;
21
+ `application_build_list` flags whether each build is released and with which semver.
22
+ 4. **Release → scopes.** `application_get` shows the live release per scope. If the change's
23
+ release is on staging but not production, that is the precise answer — and the next action is
24
+ `promoting-across-environments`.
25
+
26
+ ## Answer with a position, not a yes/no
27
+
28
+ State where the change *is*: "PROJ-123 is in release 1.4.2 — live on staging since Tuesday, not
29
+ yet on production." If it hasn't built or been released, say which step it's stuck at. Never equate
30
+ a merged PR with a deployed change; the gap between them is the whole point of the trace.
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: understand-a-service
3
+ description: Use when getting oriented on an unfamiliar or inherited nullplatform application — what it is, where it runs, what it depends on, and how it is configured — before changing anything.
4
+ ---
5
+
6
+ # Understanding a service on nullplatform
7
+
8
+ Build the picture by fusing two views — the platform's and the repo's — read-only, before you
9
+ touch anything. Establish current state AND how it got there before forming any plan.
10
+
11
+ ## 1. Resolve which app
12
+
13
+ Inside a linked repo the app is inferred from the git remote. Confirm you mean **this repo's**
14
+ app, not a similarly-named other one, and say which app (and scope) you're describing.
15
+
16
+ ## 2. The platform view
17
+
18
+ - `application_get` — what's live where: the scopes (environments) and their dimensions, the
19
+ release each one serves, and recent activity. This is the spine of the picture.
20
+ - `application_service_list` — the dependencies (databases, queues, caches…) and their status. A
21
+ dependency in a non-active state is part of "how it runs", not a footnote.
22
+ - `application_parameter_list` — the config surface (names; secret values masked). What's
23
+ configured tells you what the service expects from its environment.
24
+
25
+ ## 3. The repo view (what the dashboard can't see)
26
+
27
+ You're running in the developer's environment — read it. The `README`, `package.json` /
28
+ `Dockerfile` (language, runtime, entrypoint, ports), the default branch, and recent `git log`
29
+ (what's changing, and by whom). This is the half a web dashboard structurally lacks, and it's
30
+ where this integration earns its keep.
31
+
32
+ ## 4. Correlate the two
33
+
34
+ - Does the release on the main scope match the repo's `HEAD`? A gap means production is behind
35
+ (or ahead of) what's checked out — say so.
36
+ - How many environments are there, and how do they differ (dimensions, releases)?
37
+ - What does the service talk to, and is each dependency provisioned and active?
38
+
39
+ ## 5. Summarize, don't act
40
+
41
+ Give the user a grounded picture: what the service is, where it runs, what it depends on, how
42
+ it's configured, and what's live. For ownership, teams, and other surfaces this integration
43
+ doesn't cover, deep-link to the dashboard.
44
+
45
+ ## Don'ts
46
+
47
+ - Stay read-only until you have the picture: no deploy, config change, or scope edit while still
48
+ learning.
49
+ - Don't assume the repo you're in is the app — confirm the git remote matches before you describe
50
+ anything as fact.
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: working-from-a-ticket
3
+ description: Use when starting from a tracker work item (Jira, GitHub Issues, Linear, …) — read or create the ticket, implement it in the repo, ship it through nullplatform, and report status back to the ticket.
4
+ ---
5
+
6
+ # Working from a ticket on nullplatform
7
+
8
+ nullplatform owns the delivery half — build → release → deploy. The ticket is the *intent* half,
9
+ and it lives in the developer's own tracker, reached through whatever issue-tracker connection
10
+ they've set up (Jira, GitHub Issues, Linear, …) — not through nullplatform. Your job is to carry
11
+ one work item across the whole loop and close it. The thread that ties intent to delivery is the
12
+ **commit**: keep the issue key on the branch and the commit so the change stays traceable end to
13
+ end (see `tracing-a-change`).
14
+
15
+ ## 1. Get the work item
16
+
17
+ - Have a ticket → read it from the connected tracker. Pull out the change, the acceptance
18
+ criteria, and the issue key (e.g. `PROJ-123`).
19
+ - No ticket yet → draft one from repo + platform context (what the app is, what's live — see
20
+ `understand-a-service`) and create it in the tracker. Confirm the title and description with the
21
+ user before creating it — it's an external write.
22
+
23
+ ## 2. Implement it
24
+
25
+ Work on a branch named for the issue key, and put the key in the commit / PR. Implement against the
26
+ acceptance criteria with your normal approach — plan, code, tests — that's your own craft, not this
27
+ playbook's job. The one thing that matters here: the issue key must ride the commit, because that
28
+ is what lets the deploy be traced back to the ticket afterwards.
29
+
30
+ ## 3. Deliver it
31
+
32
+ Push so CI builds (the build records the commit). Watch it land with `application_build_list`, then
33
+ ship it with `deploying-safely`, or move it from a lower environment with
34
+ `promoting-across-environments`.
35
+
36
+ ## 4. Close the loop
37
+
38
+ Once it's live on the target scope and verified, report back to the ticket — the release it shipped
39
+ in, the environment, and the commit — and move its state. Posting to the tracker is an external
40
+ write: confirm with the user first, and don't mark a ticket done before it's actually deployed and
41
+ healthy (merged ≠ deployed).
42
+
43
+ ## Don'ts
44
+
45
+ - Don't lose the issue key — no key on the commit, no traceability back from a deploy.
46
+ - Don't create or update a tracker item without the user's ok.
47
+ - Don't close a ticket on merge; close it when the change is live and verified.
@@ -825,6 +825,6 @@ Boolean requesting whether a visible border and background is provided by the ho
825
825
  - "app": Tool callable by the app from this server only`),csp:c.never().optional(),permissions:c.never().optional()}),LS=c.object({mimeTypes:c.array(c.string()).optional().describe('Array of supported MIME types for UI resources.\nMust include `"text/html;profile=mcp-app"` for MCP Apps support.')}),MS=c.object({method:c.literal("ui/download-file"),params:c.object({contents:c.array(c.union([wl,Il])).describe("Resource contents to download \u2014 embedded (inline data) or linked (host fetches). Uses standard MCP resource types.")})}),FS=c.object({method:c.literal("ui/message"),params:c.object({role:c.literal("user").describe('Message role, currently only "user" is supported.'),content:c.array(Bt).describe("Message content blocks (text, image, etc.).")})}),qS=c.object({method:c.literal("ui/notifications/sandbox-resource-ready"),params:c.object({html:c.string().describe("HTML content to load into the inner iframe."),sandbox:c.string().optional().describe("Optional override for the inner iframe's sandbox attribute."),csp:Dl.optional().describe("CSP configuration from resource metadata."),permissions:Al.optional().describe("Sandbox permissions from resource metadata.")})}),A_=c.object({method:c.literal("ui/notifications/tool-result"),params:Jt.describe("Standard MCP tool execution result.")}),rf=c.object({toolInfo:c.object({id:qt.optional().describe("JSON-RPC id of the tools/call request."),tool:ai.describe("Tool definition including name, inputSchema, etc.")}).optional().describe("Metadata of the tool call that instantiated this App."),theme:x_.optional().describe("Current color theme preference."),styles:T_.optional().describe("Style configuration for theming the app."),displayMode:Gr.optional().describe("How the UI is currently displayed."),availableDisplayModes:c.array(Gr).optional().describe("Display modes the host supports."),containerDimensions:c.union([c.object({height:c.number().describe("Fixed container height in pixels.")}),c.object({maxHeight:c.union([c.number(),c.undefined()]).optional().describe("Maximum container height in pixels.")})]).and(c.union([c.object({width:c.number().describe("Fixed container width in pixels.")}),c.object({maxWidth:c.union([c.number(),c.undefined()]).optional().describe("Maximum container width in pixels.")})])).optional().describe(`Container dimensions. Represents the dimensions of the iframe or other
826
826
  container holding the app. Specify either width or maxWidth, and either height or maxHeight.`),locale:c.string().optional().describe("User's language and region preference in BCP 47 format."),timeZone:c.string().optional().describe("User's timezone in IANA format."),userAgent:c.string().optional().describe("Host application identifier."),platform:c.union([c.literal("web"),c.literal("desktop"),c.literal("mobile")]).optional().describe("Platform type for responsive design decisions."),deviceCapabilities:c.object({touch:c.boolean().optional().describe("Whether the device supports touch input."),hover:c.boolean().optional().describe("Whether the device supports hover interactions.")}).optional().describe("Device input capabilities."),safeAreaInsets:c.object({top:c.number().describe("Top safe area inset in pixels."),right:c.number().describe("Right safe area inset in pixels."),bottom:c.number().describe("Bottom safe area inset in pixels."),left:c.number().describe("Left safe area inset in pixels.")}).optional().describe("Mobile safe area boundaries in pixels.")}).passthrough(),C_=c.object({method:c.literal("ui/notifications/host-context-changed"),params:rf.describe("Partial context update containing only changed fields.")}),HS=c.object({method:c.literal("ui/update-model-context"),params:c.object({content:c.array(Bt).optional().describe("Context content blocks (text, image, etc.)."),structuredContent:c.record(c.string(),c.unknown().describe("Structured content for machine-readable context data.")).optional().describe("Structured content for machine-readable context data.")})}),VS=c.object({method:c.literal("ui/initialize"),params:c.object({appInfo:qr.describe("App identification (name and version)."),appCapabilities:U_.describe("Features and capabilities this app provides."),protocolVersion:c.string().describe("Protocol version this app supports.")})}),Z_=c.object({protocolVersion:c.string().describe('Negotiated protocol version string (e.g., "2025-11-21").'),hostInfo:qr.describe("Host application identification and version."),hostCapabilities:R_.describe("Features and capabilities provided by the host."),hostContext:rf.describe("Rich context about the host environment.")}).passthrough(),L_={target:"draft-2020-12"};async function ef(e,r){let n=e["~standard"];if(n.jsonSchema)return n.jsonSchema[r](L_);if(n.vendor==="zod"){let{z:i}=await Promise.resolve().then(()=>(Zr(),ml));return i.toJSONSchema(e,{io:r})}throw Error(`Schema (vendor: ${n.vendor}) does not implement Standard JSON Schema (~standard.jsonSchema). Use a library that does (zod v4, ArkType, Valibot) or wrap your schema accordingly.`)}async function tf(e,r,n=""){let i=await e["~standard"].validate(r);if(i.issues){let t=i.issues.map(o=>{let a=o.path?.map(s=>typeof s=="object"?s.key:s).join(".");return a?`${a}: ${o.message}`:o.message}).join("; ");throw Error(n+t)}return i.value}function nf(e,r=document.documentElement){for(let[n,i]of Object.entries(e))i!==void 0&&r.style.setProperty(n,i)}function of(e){if(document.getElementById("__mcp-host-fonts"))return;let r=document.createElement("style");r.id="__mcp-host-fonts",r.textContent=e,document.head.appendChild(r)}var li=class li extends Ul{constructor(n,i={},t={autoResize:!0}){super(t);M(this,"_appInfo");M(this,"_capabilities");M(this,"options");M(this,"_hostCapabilities");M(this,"_hostInfo");M(this,"_hostContext");M(this,"_registeredTools",{});M(this,"_initializedSent",!1);M(this,"eventSchemas",{toolinput:I_,toolinputpartial:P_,toolresult:A_,toolcancelled:j_,hostcontextchanged:C_});M(this,"_everHadListener",new Set);M(this,"_toolHandlersInitialized",!1);M(this,"_onteardown");M(this,"_oncalltool");M(this,"_onlisttools");M(this,"sendOpenLink",this.openLink);this._appInfo=n,this._capabilities=i,this.options=t,t.allowUnsafeEval||c.config({jitless:!0}),this.setRequestHandler(Ht,o=>(console.log("Received ping:",o.params),{})),this.setEventHandler("hostcontextchanged",void 0)}_assertInitialized(n){if(this._initializedSent)return;let i=`[ext-apps] App.${n}() called before connect() completed the ui/initialize handshake. Await app.connect() before calling this method, or move data loading to an ontoolresult handler.`;if(this.options?.strict)throw Error(i);console.warn(`${i}. This will throw in a future release.`)}_assertHandlerTiming(n){if(!li.ONE_SHOT_EVENTS.has(n)||this._everHadListener.has(n)||(this._everHadListener.add(n),!this._initializedSent))return;let i=`[ext-apps] "${String(n)}" handler registered after connect() completed the ui/initialize handshake. The host may have already sent this notification. Register handlers before calling app.connect().`;if(this.options?.strict)throw Error(i);console.warn(i)}setEventHandler(n,i){i&&this._assertHandlerTiming(n),super.setEventHandler(n,i)}addEventListener(n,i){this._assertHandlerTiming(n),super.addEventListener(n,i)}onEventDispatch(n,i){n==="hostcontextchanged"&&(this._hostContext={...this._hostContext,...i})}registerCapabilities(n){if(this.transport)throw Error("Cannot register capabilities after transport is established");this._capabilities=Ym(this._capabilities,n)}registerTool(n,i,t){if(this._registeredTools[n])throw Error(`Tool ${n} is already registered`);let o=this,a=()=>{o._initializedSent&&o._capabilities.tools?.listChanged&&o.sendToolListChanged()},s=i.inputSchema!==void 0,u={title:i.title,description:i.description,inputSchema:i.inputSchema,outputSchema:i.outputSchema,annotations:i.annotations,_meta:i._meta,enabled:!0,enable(){this.enabled=!0,a()},disable(){this.enabled=!1,a()},update(p){Object.assign(this,p),a()},remove(){o._registeredTools[n]===u&&(delete o._registeredTools[n],a())},handler:async(p,m)=>{if(!u.enabled)throw Error(`Tool ${n} is disabled`);let l;if(s){let b=u.inputSchema,v=b?await tf(b,p??{},`Invalid input for tool ${n}: `):p??{};l=await t(v,m)}else l=await t(m);return u.outputSchema&&!l.isError&&(l.structuredContent=await tf(u.outputSchema,l.structuredContent,`Invalid output for tool ${n}: `)),l}};return this._registeredTools[n]=u,!this._capabilities.tools&&!this.transport&&this.registerCapabilities({tools:{listChanged:!0}}),this.ensureToolHandlersInitialized(),a(),u}ensureToolHandlersInitialized(){this._toolHandlersInitialized||(this._toolHandlersInitialized=!0,this.oncalltool=async(n,i)=>{let t=this._registeredTools[n.name];if(!t)throw Error(`Tool ${n.name} not found`);return t.handler(n.arguments,i)},this.onlisttools=async(n,i)=>({tools:await Promise.all(Object.entries(this._registeredTools).filter(([t,o])=>o.enabled).map(async([t,o])=>{let a={name:t,title:o.title,description:o.description,inputSchema:o.inputSchema?await ef(o.inputSchema,"input"):{type:"object",properties:{}}};return o.outputSchema&&(a.outputSchema=await ef(o.outputSchema,"output")),o.annotations&&(a.annotations=o.annotations),o._meta&&(a._meta=o._meta),a}))}))}async sendToolListChanged(n={}){this._assertInitialized("sendToolListChanged"),await this.notification({method:"notifications/tools/list_changed",params:n})}getHostCapabilities(){return this._hostCapabilities}getHostVersion(){return this._hostInfo}getHostContext(){return this._hostContext}get ontoolinput(){return this.getEventHandler("toolinput")}set ontoolinput(n){this.setEventHandler("toolinput",n)}get ontoolinputpartial(){return this.getEventHandler("toolinputpartial")}set ontoolinputpartial(n){this.setEventHandler("toolinputpartial",n)}get ontoolresult(){return this.getEventHandler("toolresult")}set ontoolresult(n){this.setEventHandler("toolresult",n)}get ontoolcancelled(){return this.getEventHandler("toolcancelled")}set ontoolcancelled(n){this.setEventHandler("toolcancelled",n)}get onhostcontextchanged(){return this.getEventHandler("hostcontextchanged")}set onhostcontextchanged(n){this.setEventHandler("hostcontextchanged",n)}get onteardown(){return this._onteardown}set onteardown(n){this.warnIfRequestHandlerReplaced("onteardown",this._onteardown,n),this._onteardown=n,this.replaceRequestHandler(O_,(i,t)=>{if(!this._onteardown)throw Error("No onteardown handler set");return this._onteardown(i.params,t)})}get oncalltool(){return this._oncalltool}set oncalltool(n){this.warnIfRequestHandlerReplaced("oncalltool",this._oncalltool,n),this._oncalltool=n,this.replaceRequestHandler(jl,(i,t)=>{if(!this._oncalltool)throw Error("No oncalltool handler set");return this._oncalltool(i.params,t)})}get onlisttools(){return this._onlisttools}set onlisttools(n){this.warnIfRequestHandlerReplaced("onlisttools",this._onlisttools,n),this._onlisttools=n,this.replaceRequestHandler(Pl,(i,t)=>{if(!this._onlisttools)throw Error("No onlisttools handler set");return this._onlisttools(i.params,t)})}assertCapabilityForMethod(n){switch(n){case"sampling/createMessage":if(!this._hostCapabilities?.sampling)throw Error(`Host does not support sampling (required for ${n})`);break}}assertRequestHandlerCapability(n){switch(n){case"tools/call":case"tools/list":if(!this._capabilities.tools)throw Error(`Client does not support tool capability (required for ${n})`);return;case"ping":case"ui/resource-teardown":return;default:throw Error(`No handler for method ${n} registered`)}}assertNotificationCapability(n){}assertTaskCapability(n){throw Error("Tasks are not supported in MCP Apps")}assertTaskHandlerCapability(n){throw Error("Task handlers are not supported in MCP Apps")}async callServerTool(n,i){if(this._assertInitialized("callServerTool"),typeof n=="string")throw Error(`callServerTool() expects an object as its first argument, but received a string ("${n}"). Did you mean: callServerTool({ name: "${n}", arguments: { ... } })?`);return await this.request({method:"tools/call",params:n},Jt,{onprogress:()=>{},resetTimeoutOnProgress:!0,...i})}async readServerResource(n,i){return this._assertInitialized("readServerResource"),await this.request({method:"resources/read",params:n},$l,i)}async listServerResources(n,i){return this._assertInitialized("listServerResources"),await this.request({method:"resources/list",params:n},yl,i)}async createSamplingMessage(n,i){this._assertInitialized("createSamplingMessage");let t=n.tools?Tl:Nl;return await this.request({method:"sampling/createMessage",params:n},t,i)}sendMessage(n,i){return this._assertInitialized("sendMessage"),this.request({method:"ui/message",params:n},w_,i)}sendLog(n){return this.notification({method:"notifications/message",params:n})}updateModelContext(n,i){return this._assertInitialized("updateModelContext"),this.request({method:"ui/update-model-context",params:n},Go,i)}openLink(n,i){return this._assertInitialized("openLink"),this.request({method:"ui/open-link",params:n},z_,i)}downloadFile(n,i){return this._assertInitialized("downloadFile"),this.request({method:"ui/download-file",params:n},S_,i)}requestTeardown(n={}){return this.notification({method:"ui/notifications/request-teardown",params:n})}requestDisplayMode(n,i){return this._assertInitialized("requestDisplayMode"),this.request({method:"ui/request-display-mode",params:n},E_,i)}sendSizeChanged(n){return this.notification({method:"ui/notifications/size-changed",params:n})}setupSizeChangedNotifications(){let n=!1,i=0,t=0,o=()=>{n||(n=!0,requestAnimationFrame(()=>{n=!1;let s=document.documentElement,u=s.style.height;s.style.height="max-content";let p=Math.ceil(s.getBoundingClientRect().height);s.style.height=u;let m=Math.ceil(window.innerWidth);(m!==i||p!==t)&&(i=m,t=p,this.sendSizeChanged({width:m,height:p}))}))};o();let a=new ResizeObserver(o);return a.observe(document.documentElement),a.observe(document.body),()=>a.disconnect()}async connect(n=new El(window.parent,window.parent),i){if(this.transport)throw Error("App is already connected. Call close() before connecting again.");this._initializedSent=!1,await super.connect(n);try{let t=await this.request({method:"ui/initialize",params:{appCapabilities:this._capabilities,appInfo:this._appInfo,protocolVersion:b_}},Z_,i);if(t===void 0)throw Error(`Server sent invalid initialize result: ${t}`);this._hostCapabilities=t.hostCapabilities,this._hostInfo=t.hostInfo,this._hostContext=t.hostContext,await this.notification({method:"ui/notifications/initialized"}),this._initializedSent=!0,this.options?.autoResize&&this.setupSizeChangedNotifications()}catch(t){throw this.close(),t}}};M(li,"ONE_SHOT_EVENTS",new Set(["toolinput","toolinputpartial","toolresult","toolcancelled"]));var ci=li;var sf=e=>(e?.content??[]).map(r=>r.text??"").join(`
827
827
  `);function M_(e){if(!e)return;let r=e.trim().toLowerCase(),n,i,t,o=/^#([0-9a-f]{3}|[0-9a-f]{6})$/.exec(r)?.[1];if(o){let a=o.length===3?o.split("").map(s=>s+s).join(""):o;n=parseInt(a.slice(0,2),16),i=parseInt(a.slice(2,4),16),t=parseInt(a.slice(4,6),16)}else{let a=/^rgba?\(\s*([\d.]+)[ ,]+([\d.]+)[ ,]+([\d.]+)/.exec(r);a&&([n,i,t]=[Number(a[1]),Number(a[2]),Number(a[3])]);let s=/^hsla?\(\s*[\d.]+[ ,]+[\d.]+%?[ ,]+([\d.]+)%/.exec(r);if(s)return Number(s[1])/100}if(!(n===void 0||i===void 0||t===void 0))return(.2126*n+.7152*i+.0722*t)/255}function af(e){if(!e)return;let r=document.documentElement,n=e.theme==="dark"||e.theme==="light"?e.theme:void 0,i=e.styles?.variables;if(!n&&i){let t=M_(i["--color-background-primary"]??i["--color-background-secondary"]);t!==void 0&&(n=t<.5?"dark":"light")}n&&(r.classList.toggle("dark",n==="dark"),r.classList.toggle("light",n==="light"),r.style.colorScheme=n);try{i&&nf(i),e.styles?.css?.fonts&&of(e.styles.css.fonts)}catch{}console.debug("[np-widget] theme:",e.theme,"->",n??"os-fallback","| tokens:",!!i,"| fonts:",!!e.styles?.css?.fonts)}function cf(e){let[r,n]=re(null),[i,t]=re(!1),o=ln(null);pt(()=>{let p=new ci({name:e,version:"0.3.0"},{},{autoResize:!0});o.current=p,p.ontoolresult=m=>n(m),p.onhostcontextchanged=m=>af(m),p.connect().then(()=>{af(p.getHostContext()),t(!0)}).catch(()=>t(!1))},[e]);let a=Me(async(p,m)=>{if(!o.current)throw new Error("not connected");return await o.current.callServerTool({name:p,arguments:m})},[]),s=Me(p=>{o.current?.sendMessage({role:"user",content:[{type:"text",text:p}]}).catch(()=>{})},[]),u=Me(p=>{try{o.current?.updateModelContext({content:[{type:"text",text:p}]}).catch(()=>{})}catch{}},[]);return{result:r,call:a,send:s,brief:u,connected:i}}var F_={"confirm.yes":"Yes, do it","confirm.no":"Cancel","chooser.pick":"pick a scope:","term.empty":"no output yet\u2026","term.copyLine":"copy line",hint:"Next:","panel.scopes":"Scopes","panel.releases":"Releases","panel.latestBuild":"Latest build","panel.noScopes":"No scopes yet \u2014 create one to have somewhere to deploy.","panel.scopePlaceholder":"scope name, e.g. dev","panel.typePlaceholder":"type\u2026","panel.createScope":"Create scope","panel.ship":"ship","panel.live":"live","panel.openRollout":"Open rollout","panel.nothingDeployed":"nothing deployed","panel.noReleases":"none yet","panel.noBuild":"none \u2014 push a commit so CI builds","panel.deployLatest":"Deploy latest","panel.logs":"Logs","panel.metrics":"Metrics","panel.pickType":"Pick a scope type and create again.","panel.waitingData":"waiting for data\u2026","panel.backToList":"apps","rollout.deployingTo":"Deploying to {scope}","rollout.release":"release","rollout.backToApp":"app","rollout.trafficLabel":"Traffic on new version","rollout.live":"{pct}% live","rollout.movingTo":"moving to {pct}%","rollout.move":"Move traffic","rollout.finalize":"Finalize","rollout.rollback":"Rollback","rollout.confirmFinalize":"Finalize and retire the old version?","rollout.confirmRollback":"Return ALL traffic to the previous version?","rollout.log":"Deployment log","rollout.waiting":"waiting for activity\u2026","rollout.failed":"Failed: {message}","rollout.deployment":"Deployment #{id}","rollout.busyMove":"Moving traffic\u2026","rollout.busyFinalize":"Finalizing\u2026","rollout.busyRollback":"Rolling back\u2026","rollout.autoDone":"Done \u2014 the release is fully live.","rollout.autoRolledBack":"Rolled back \u2014 previous version is serving traffic.","rollout.autoFailed":"Deployment failed \u2014 previous version keeps serving.","rollout.autoWaiting":"Waiting for instances \u2014 controls unlock when the rollout is running.","rollout.autoFull":"All traffic on the new version \u2014 finalize to retire the old one.","rollout.autoLabel":"Auto-advance","rollout.autoOff":"off","rollout.trafficHelp":"Drag to move traffic now; auto-advance ramps it to 100%.","rollout.appLogs":"Application logs","rollout.appLogsEmpty":"no application logs yet\u2026","logs.title":"{app} \xB7 logs","logs.heading":"Logs","logs.filter":"filter\u2026","logs.live":"live","logs.refresh":"Refresh","logs.updated":"updated {time}","logs.wrap":"Wrap","logs.copyAll":"Copy all","logs.copied":"Copied","logs.rangeLive":"Live","logs.range15m":"Last 15m","logs.range1h":"Last 1h","logs.range6h":"Last 6h","logs.range24h":"Last 24h","logs.rangeCustom":"Custom\u2026","logs.apply":"Apply","logs.from":"From","logs.to":"To","logs.empty":"no log lines yet\u2026","logs.noMatch":"nothing matches the filter","logs.count":"{count} line(s){scope}","logs.scopeSuffix":" \xB7 scope {scope}","logs.refreshFailed":"refresh failed: {message}","metrics.title":"{app} \xB7 {scope} metrics","metrics.heading":"Metrics","metrics.live":"live","metrics.loading":"loading {window}\u2026","metrics.refreshFailed":"refresh failed: {message}","metrics.noData":"no datapoints in this window","metrics.avgMax":"avg {avg} \xB7 max {max}","params.title":"{app} \xB7 parameters","params.heading":"Parameters","params.name":"Name","params.value":"Value","params.secret":"Secret","params.add":"+ Add","params.save":"Save changes","params.applyNote":"Changed values apply on the next deploy.","params.unavailable":"Existing values can't be listed here \u2014 new ones can still be added below.","params.saving":"Saving {count} parameter(s)\u2026","params.saved":"Saved \u2014 values apply on the next deploy.","params.saveFailed":"Save failed: {message}","createApp.title":"Create application","createApp.name":"Name","createApp.namespace":"Namespace","createApp.repository":"Repository","createApp.newRepo":"New repository","createApp.importRepo":"Import existing","createApp.template":"Template","createApp.noTemplates":"No templates available","createApp.repoUrl":"Repository URL","createApp.editName":"Customize the repository name","createApp.lockName":"Reset to the generated name","createApp.importUrl":"Existing repository URL","createApp.monorepo":"This repository is a monorepo","createApp.appPath":"Application path inside the repository","createApp.submit":"Create application","createApp.needName":"Name is required.","createApp.needNamespace":"Pick a namespace.","createApp.needTemplate":"Pick a template for the new repository.","createApp.needImportUrl":"Enter the repository URL to import.","createApp.noBaseUrl":"This account has no git provider configured \u2014 use \u201CImport existing\u201D.","createApp.creating":"Creating {name}\u2026 (links the repo, wires CI \u2014 takes a few seconds)","createApp.failed":"Failed: {message}","createApp.created":`{name} created (#{id}, {status}).
828
- Push a commit to trigger the first build, then deploy.`,"findApps.count":"{count} application(s)","findApps.filter":"filter\u2026","findApps.across":"across {ns} namespace(s)","findApps.noMatch":"Nothing matches the filter.","findApps.page":"{from}\u2013{to} of {total}","findApps.prevPage":"Previous page","findApps.nextPage":"Next page","findApps.hint":"Click an application to open its panel."},q_={"confirm.yes":"S\xED, hacelo","confirm.no":"Cancelar","chooser.pick":"eleg\xED un scope:","term.empty":"sin salida todav\xEDa\u2026","term.copyLine":"copiar l\xEDnea",hint:"Siguiente:","panel.scopes":"Scopes","panel.releases":"Releases","panel.latestBuild":"\xDAltimo build","panel.noScopes":"Sin scopes todav\xEDa \u2014 cre\xE1 uno para tener d\xF3nde deployar.","panel.scopePlaceholder":"nombre del scope, p. ej. dev","panel.typePlaceholder":"tipo\u2026","panel.createScope":"Crear scope","panel.ship":"publicar","panel.live":"en vivo","panel.openRollout":"Abrir rollout","panel.nothingDeployed":"nada deployado","panel.noReleases":"ninguna todav\xEDa","panel.noBuild":"ninguno \u2014 pushe\xE1 un commit para que CI compile","panel.deployLatest":"Deployar lo \xFAltimo","panel.logs":"Logs","panel.metrics":"M\xE9tricas","panel.pickType":"Eleg\xED un tipo de scope y cre\xE1 de nuevo.","panel.waitingData":"esperando datos\u2026","panel.backToList":"apps","rollout.deployingTo":"Deployando a {scope}","rollout.release":"release","rollout.backToApp":"app","rollout.trafficLabel":"Tr\xE1fico en la versi\xF3n nueva","rollout.live":"{pct}% en vivo","rollout.movingTo":"yendo a {pct}%","rollout.move":"Mover tr\xE1fico","rollout.finalize":"Finalizar","rollout.rollback":"Revertir","rollout.confirmFinalize":"\xBFFinalizar y retirar la versi\xF3n anterior?","rollout.confirmRollback":"\xBFDevolver TODO el tr\xE1fico a la versi\xF3n anterior?","rollout.log":"Log del deployment","rollout.waiting":"esperando actividad\u2026","rollout.failed":"Fall\xF3: {message}","rollout.deployment":"Deployment #{id}","rollout.busyMove":"Moviendo tr\xE1fico\u2026","rollout.busyFinalize":"Finalizando\u2026","rollout.busyRollback":"Revirtiendo\u2026","rollout.autoDone":"Listo \u2014 la release est\xE1 completamente en vivo.","rollout.autoRolledBack":"Revertido \u2014 la versi\xF3n anterior est\xE1 sirviendo tr\xE1fico.","rollout.autoFailed":"El deployment fall\xF3 \u2014 la versi\xF3n anterior sigue sirviendo.","rollout.autoWaiting":"Esperando instancias \u2014 los controles se habilitan cuando el rollout est\xE1 corriendo.","rollout.autoFull":"Todo el tr\xE1fico en la versi\xF3n nueva \u2014 finaliz\xE1 para retirar la anterior.","rollout.autoLabel":"Auto-avance","rollout.autoOff":"off","rollout.trafficHelp":"Arrastr\xE1 para mover el tr\xE1fico ahora; el auto-avance sube hasta 100%.","rollout.appLogs":"Logs de la aplicaci\xF3n","rollout.appLogsEmpty":"sin logs de la aplicaci\xF3n todav\xEDa\u2026","logs.title":"{app} \xB7 logs","logs.heading":"Logs","logs.filter":"filtrar\u2026","logs.live":"vivo","logs.refresh":"Refrescar","logs.updated":"actualizado {time}","logs.wrap":"Ajustar","logs.copyAll":"Copiar todo","logs.copied":"Copiado","logs.rangeLive":"En vivo","logs.range15m":"\xDAltimos 15m","logs.range1h":"\xDAltima 1h","logs.range6h":"\xDAltimas 6h","logs.range24h":"\xDAltimas 24h","logs.rangeCustom":"Personalizado\u2026","logs.apply":"Aplicar","logs.from":"Desde","logs.to":"Hasta","logs.empty":"sin l\xEDneas de log todav\xEDa\u2026","logs.noMatch":"nada coincide con el filtro","logs.count":"{count} l\xEDnea(s){scope}","logs.scopeSuffix":" \xB7 scope {scope}","logs.refreshFailed":"fall\xF3 el refresh: {message}","metrics.title":"{app} \xB7 m\xE9tricas de {scope}","metrics.heading":"M\xE9tricas","metrics.live":"vivo","metrics.loading":"cargando {window}\u2026","metrics.refreshFailed":"fall\xF3 el refresh: {message}","metrics.noData":"sin datapoints en esta ventana","metrics.avgMax":"prom {avg} \xB7 m\xE1x {max}","params.title":"{app} \xB7 par\xE1metros","params.heading":"Par\xE1metros","params.name":"Nombre","params.value":"Valor","params.secret":"Secreto","params.add":"+ Agregar","params.save":"Guardar cambios","params.applyNote":"Los valores cambiados aplican en el pr\xF3ximo deploy.","params.unavailable":"Los valores existentes no se pueden listar ac\xE1 \u2014 igual pod\xE9s agregar nuevos abajo.","params.saving":"Guardando {count} par\xE1metro(s)\u2026","params.saved":"Guardado \u2014 los valores aplican en el pr\xF3ximo deploy.","params.saveFailed":"Fall\xF3 el guardado: {message}","createApp.title":"Crear aplicaci\xF3n","createApp.name":"Nombre","createApp.namespace":"Namespace","createApp.repository":"Repositorio","createApp.newRepo":"Nuevo repositorio","createApp.importRepo":"Importar existente","createApp.template":"Template","createApp.noTemplates":"Sin templates disponibles","createApp.repoUrl":"URL del repositorio","createApp.editName":"Personalizar el nombre del repositorio","createApp.lockName":"Volver al nombre generado","createApp.importUrl":"URL del repositorio existente","createApp.monorepo":"Este repositorio es un monorepo","createApp.appPath":"Ruta de la aplicaci\xF3n dentro del repositorio","createApp.submit":"Crear aplicaci\xF3n","createApp.needName":"El nombre es obligatorio.","createApp.needNamespace":"Eleg\xED un namespace.","createApp.needTemplate":"Eleg\xED un template para el nuevo repositorio.","createApp.needImportUrl":"Ingres\xE1 la URL del repositorio a importar.","createApp.noBaseUrl":"Esta cuenta no tiene proveedor de git configurado \u2014 us\xE1 \u201CImportar existente\u201D.","createApp.creating":"Creando {name}\u2026 (vincula el repo, conecta CI \u2014 tarda unos segundos)","createApp.failed":"Fall\xF3: {message}","createApp.created":`{name} creada (#{id}, {status}).
829
- Pushe\xE1 un commit para disparar el primer build y despu\xE9s deploy\xE1.`,"findApps.count":"{count} aplicaci\xF3n(es)","findApps.filter":"filtrar\u2026","findApps.across":"en {ns} namespace(s)","findApps.noMatch":"Nada coincide con el filtro.","findApps.page":"{from}\u2013{to} de {total}","findApps.prevPage":"P\xE1gina anterior","findApps.nextPage":"P\xE1gina siguiente","findApps.hint":"Hac\xE9 clic en una aplicaci\xF3n para abrir su panel."},H_={en:F_,es:q_};function lf(e){return e?.structuredContent?._locale==="es"?"es":"en"}function uf(e){let r=H_[e];return(n,i)=>r[n].replace(/\{(\w+)\}/g,(t,o)=>i?.[o]!==void 0?String(i[o]):t)}var V_=sn(uf("en")),pf=V_.Provider;var df=e=>uf(e);function mf(e){return{render:function(r){ju(r,e)},unmount:function(){Tu(e)}}}function ff(e){let r=document.getElementById("root");r&&mf(r).render(e)}var B_=0;function h(e,r,n,i,t,o){r||(r={});var a,s,u=r;if("ref"in u)for(s in u={},r)s=="ref"?a=r[s]:u[s]=r[s];var p={type:e,props:u,key:n,ref:a,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--B_,__i:-1,__u:0,__source:t,__self:o};if(typeof e=="function"&&(a=e.defaultProps))for(s in a)u[s]===void 0&&(u[s]=a[s]);return U.vnode&&U.vnode(p),p}var J_={clock:{body:h(V,{children:[h("circle",{cx:"12",cy:"12",r:"10"}),h("polyline",{points:"12 6 12 12 16 14"})]})},play:{fill:!0,body:h("polygon",{points:"6 3 20 12 6 21 6 3"})},pause:{fill:!0,body:h(V,{children:[h("rect",{x:"6",y:"4",width:"4",height:"16",rx:"1"}),h("rect",{x:"14",y:"4",width:"4",height:"16",rx:"1"})]})},refresh:{body:h(V,{children:[h("path",{d:"M21 12a9 9 0 1 1-2.64-6.36"}),h("polyline",{points:"21 3 21 8 16 8"})]})},rocket:{body:h(V,{children:[h("path",{d:"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"}),h("path",{d:"m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"}),h("path",{d:"M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"}),h("path",{d:"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"})]})},logs:{body:h(V,{children:[h("path",{d:"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"}),h("polyline",{points:"14 2 14 8 20 8"}),h("line",{x1:"16",y1:"13",x2:"8",y2:"13"}),h("line",{x1:"16",y1:"17",x2:"8",y2:"17"}),h("line",{x1:"10",y1:"9",x2:"8",y2:"9"})]})},metrics:{body:h(V,{children:[h("polyline",{points:"22 7 13.5 15.5 8.5 10.5 2 17"}),h("polyline",{points:"16 7 22 7 22 13"})]})},lock:{body:h(V,{children:[h("rect",{x:"3",y:"11",width:"18",height:"11",rx:"2",ry:"2"}),h("path",{d:"M7 11V7a5 5 0 0 1 10 0v4"})]})},edit:{body:h("path",{d:"M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"})},copy:{body:h(V,{children:[h("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),h("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]})},check:{body:h("polyline",{points:"20 6 9 17 4 12"})},chevronDown:{body:h("polyline",{points:"6 9 12 15 18 9"})},chevronLeft:{body:h("polyline",{points:"15 18 9 12 15 6"})},chevronRight:{body:h("polyline",{points:"9 18 15 12 9 6"})},arrowLeft:{body:h(V,{children:[h("line",{x1:"19",y1:"12",x2:"5",y2:"12"}),h("polyline",{points:"12 19 5 12 12 5"})]})}},Cl=({name:e,size:r=14,className:n})=>{let i=J_[e];return h("svg",{className:["icon",n].filter(Boolean).join(" "),width:r,height:r,viewBox:"0 0 24 24",fill:i.fill?"currentColor":"none",stroke:i.fill?"none":"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",focusable:"false",children:i.body})};var Zl=({children:e})=>h("div",{className:"card",children:e}),W_=({children:e})=>h("div",{className:"row",children:e});var Ll=({tone:e,children:r})=>h("div",{className:`note${e?` ${e}`:""}`,children:r});var Qr=({variant:e,on:r,className:n,...i})=>h("button",{className:[e,r?"on":"",n].filter(Boolean).join(" "),...i}),Wt=({label:e,children:r})=>h("div",{className:"field",children:[h("div",{className:"label",children:e}),r]});var Q=({w:e="100%",h:r=12,r:n=6})=>h("div",{className:"skel",style:{width:e,height:r,borderRadius:n}}),gf=({variant:e})=>h(Zl,{children:[h(W_,{children:[h(Q,{w:170,h:16}),e!=="form"&&h(V,{children:[h("div",{className:"grow"}),h(Q,{w:110,h:28,r:8})]})]}),e==="list"&&h("div",{className:"skel-rows",children:[0,1,2,3,4,5].map(r=>h("div",{className:"skel-row",children:[h(Q,{w:8,h:8,r:999}),h(Q,{w:140,h:13}),h("div",{className:"grow"}),h(Q,{w:90,h:11})]},r))}),e==="panel"&&h(V,{children:[h("div",{className:"section",children:[h(Q,{w:64,h:10}),h("div",{style:{marginTop:10,display:"flex",flexDirection:"column",gap:10},children:[0,1].map(r=>h("div",{className:"skel-card",children:[h(Q,{w:r?"45%":"55%",h:14}),h("div",{style:{height:8}}),h(Q,{w:r?"70%":"85%",h:11})]},r))})]}),h("div",{className:"section",children:[h(Q,{w:64,h:10}),h("div",{style:{marginTop:10,display:"flex",gap:8},children:[0,1,2].map(r=>h(Q,{w:72,h:24,r:999},r))})]}),h("div",{className:"section",style:{display:"flex",gap:8},children:[h(Q,{w:132,h:34,r:9}),h(Q,{w:80,h:34,r:9})]})]}),e==="table"&&h("div",{className:"skel-rows",children:[0,1,2,3].map(r=>h("div",{className:"skel-row",children:[h(Q,{w:"30%",h:13}),h("div",{className:"grow"}),h(Q,{w:"42%",h:13}),h(Q,{w:18,h:13})]},r))}),e==="grid"&&h("div",{className:"skel-grid",children:[0,1,2,3].map(r=>h("div",{className:"skel-card",children:[h(Q,{w:"50%",h:10}),h("div",{style:{height:8}}),h(Q,{w:"35%",h:20}),h("div",{style:{height:8}}),h(Q,{w:"100%",h:40,r:8})]},r))}),e==="logs"&&h("div",{style:{marginTop:14},children:h(Q,{w:"100%",h:150,r:10})}),e==="form"&&h("div",{className:"skel-rows",children:[[0,1,2].map(r=>h("div",{children:[h(Q,{w:88,h:10}),h("div",{style:{height:7}}),h(Q,{w:"100%",h:32,r:8})]},r)),h(Q,{w:150,h:34,r:9})]})]});function K_(){let{result:e,call:r,brief:n}=cf("np-create-app"),i=Ge(()=>df(lf(e)),[e]),[t,o]=re([]),[a,s]=re([]),[u,p]=re(""),[m,l]=re(null),[b,v]=re("new"),[f,$]=re(null),[k,j]=re(""),[y,P]=re(!0),[O,ue]=re(""),[$e,Oe]=re(!1),[Se,be]=re(""),[Re,Ml]=re(!1),[hf,vf]=re(!1),[Fl,Ue]=re({text:""}),Kt=Me(E=>{let de=E?.structuredContent;if(de?.mode==="form"){let We=de.namespaces??[],di=de.templates??[];o(We),s(di),de.prefill?.name&&p(lt=>lt||de.prefill?.name||""),l(lt=>lt??de.prefill?.namespace_id??We[0]?.id??null),$(lt=>di.some(xf=>xf.id===lt)?lt:di[0]?.id??null);return}if(de?.application){let We=de.application;vf(!0),Ue({tone:We.status==="active"?"ok":void 0,text:i("createApp.created",{name:We.name,id:We.id,status:We.status})});return}let ql=sf(E);ql&&Ue({text:ql.slice(0,300)})},[i]);pt(()=>Kt(e),[e,Kt]);let _f=Me(async E=>{try{Kt(await r(Ii.applicationCreate,{namespace_id:E}))}catch{}},[Kt,r]),Yr=Ge(()=>t.find(E=>E.id===m),[t,m]),ct=Yr?.base_url??null,ui=Ge(()=>Yr&&u.trim()?`${rr(Yr.name)}-${rr(u)}`:rr(u),[Yr,u]),pi=y?ui:k||ui,bf=ct&&pi?`${ct}/${pi}`:"",yf=async()=>{if(Re)return;if(!u.trim())return Ue({tone:"bad",text:i("createApp.needName")});if(!m)return Ue({tone:"bad",text:i("createApp.needNamespace")});let E={name:u.trim(),namespace_id:m};if(b==="new"){if(!ct)return Ue({tone:"bad",text:i("createApp.noBaseUrl")});if(!f)return Ue({tone:"bad",text:i("createApp.needTemplate")});E.repository_url=bf,E.template_id=f}else{if(!O.trim())return Ue({tone:"bad",text:i("createApp.needImportUrl")});E.repository_url=O.trim(),$e&&Se.trim()&&(E.repository_app_path=Se.trim().replace(/^\/+|\/+$/g,""))}Ml(!0),Ue({text:i("createApp.creating",{name:u.trim()})});try{Kt(await r(Ii.applicationCreate,E)),n(`[create-app] user created application "${u.trim()}" from the widget.`)}catch(de){Ue({tone:"bad",text:i("createApp.failed",{message:Ou(de)})})}Ml(!1)};return e?h(pf,{value:i,children:h(Zl,{children:[h("div",{className:"title",style:{marginBottom:12},children:i("createApp.title")}),!hf&&h(V,{children:[h(Wt,{label:i("createApp.name"),children:h("input",{type:"text",placeholder:"my-service",autoComplete:"off",value:u,onChange:E=>p(E.target.value)})}),h(Wt,{label:i("createApp.namespace"),children:h("select",{value:m??"",onChange:E=>{let de=Number(E.target.value)||null;l(de),de&&_f(de)},children:t.map(E=>h("option",{value:E.id,children:[E.name,E.account?` \u2014 ${E.account}`:""]},E.id))})}),h("div",{className:"field",children:[h("div",{className:"label",children:i("createApp.repository")}),h("div",{className:"segmented",children:[h(Qr,{variant:"small",on:b==="new",className:"seg",onClick:()=>v("new"),children:i("createApp.newRepo")}),h(Qr,{variant:"small",on:b==="import",className:"seg",onClick:()=>v("import"),children:i("createApp.importRepo")})]})]}),b==="new"?h(V,{children:[h(Wt,{label:i("createApp.template"),children:h("select",{value:f??"",onChange:E=>$(Number(E.target.value)||null),children:[a.length===0&&h("option",{value:"",children:i("createApp.noTemplates")}),a.map(E=>h("option",{value:E.id,children:[E.name,E.tags?.length?` \xB7 ${E.tags.slice(0,2).join(", ")}`:""]},E.id))]})}),h("div",{className:"field",children:[h("div",{className:"label",children:i("createApp.repoUrl")}),ct?h("div",{className:"repo-url",children:[h("span",{className:"repo-base",title:ct,children:[ct,"/"]}),h("input",{type:"text",className:"grow mono",value:pi,disabled:y,spellCheck:!1,onChange:E=>j(rr(E.target.value))}),h(Qr,{variant:"small",className:"hasicon",title:i(y?"createApp.editName":"createApp.lockName"),"aria-label":i(y?"createApp.editName":"createApp.lockName"),on:!y,onClick:()=>{P(E=>(E&&j(ui),!E))},children:h(Cl,{name:y?"edit":"lock"})})]}):h(Ll,{tone:"bad",children:i("createApp.noBaseUrl")})]})]}):h(V,{children:[h(Wt,{label:i("createApp.importUrl"),children:h("input",{type:"text",className:"mono",placeholder:"https://github.com/org/existing-repo",autoComplete:"off",spellCheck:!1,value:O,onChange:E=>ue(E.target.value)})}),h("label",{className:"check-row",children:[h("input",{type:"checkbox",checked:$e,onChange:E=>Oe(E.target.checked)}),h("span",{children:i("createApp.monorepo")})]}),$e&&h(Wt,{label:i("createApp.appPath"),children:h("input",{type:"text",className:"mono",placeholder:"services/my-app",autoComplete:"off",spellCheck:!1,value:Se,onChange:E=>be(E.target.value)})})]}),h(Qr,{variant:"primary",disabled:Re,onClick:()=>{yf()},style:{marginTop:4},children:i("createApp.submit")})]}),h(Ll,{tone:Fl.tone,children:Fl.text})]})}):h(gf,{variant:"form"})}ff(h(K_,{}));})();
828
+ Push a commit to trigger the first build, then deploy.`,"findApps.count":"{count} application(s)","findApps.filter":"filter\u2026","findApps.across":"across {ns} namespace(s)","findApps.noMatch":"Nothing matches the filter.","findApps.loadMore":"Load {more} more","findApps.hint":"Click an application to open its panel."},q_={"confirm.yes":"S\xED, hacelo","confirm.no":"Cancelar","chooser.pick":"eleg\xED un scope:","term.empty":"sin salida todav\xEDa\u2026","term.copyLine":"copiar l\xEDnea",hint:"Siguiente:","panel.scopes":"Scopes","panel.releases":"Releases","panel.latestBuild":"\xDAltimo build","panel.noScopes":"Sin scopes todav\xEDa \u2014 cre\xE1 uno para tener d\xF3nde deployar.","panel.scopePlaceholder":"nombre del scope, p. ej. dev","panel.typePlaceholder":"tipo\u2026","panel.createScope":"Crear scope","panel.ship":"publicar","panel.live":"en vivo","panel.openRollout":"Abrir rollout","panel.nothingDeployed":"nada deployado","panel.noReleases":"ninguna todav\xEDa","panel.noBuild":"ninguno \u2014 pushe\xE1 un commit para que CI compile","panel.deployLatest":"Deployar lo \xFAltimo","panel.logs":"Logs","panel.metrics":"M\xE9tricas","panel.pickType":"Eleg\xED un tipo de scope y cre\xE1 de nuevo.","panel.waitingData":"esperando datos\u2026","panel.backToList":"apps","rollout.deployingTo":"Deployando a {scope}","rollout.release":"release","rollout.backToApp":"app","rollout.trafficLabel":"Tr\xE1fico en la versi\xF3n nueva","rollout.live":"{pct}% en vivo","rollout.movingTo":"yendo a {pct}%","rollout.move":"Mover tr\xE1fico","rollout.finalize":"Finalizar","rollout.rollback":"Revertir","rollout.confirmFinalize":"\xBFFinalizar y retirar la versi\xF3n anterior?","rollout.confirmRollback":"\xBFDevolver TODO el tr\xE1fico a la versi\xF3n anterior?","rollout.log":"Log del deployment","rollout.waiting":"esperando actividad\u2026","rollout.failed":"Fall\xF3: {message}","rollout.deployment":"Deployment #{id}","rollout.busyMove":"Moviendo tr\xE1fico\u2026","rollout.busyFinalize":"Finalizando\u2026","rollout.busyRollback":"Revirtiendo\u2026","rollout.autoDone":"Listo \u2014 la release est\xE1 completamente en vivo.","rollout.autoRolledBack":"Revertido \u2014 la versi\xF3n anterior est\xE1 sirviendo tr\xE1fico.","rollout.autoFailed":"El deployment fall\xF3 \u2014 la versi\xF3n anterior sigue sirviendo.","rollout.autoWaiting":"Esperando instancias \u2014 los controles se habilitan cuando el rollout est\xE1 corriendo.","rollout.autoFull":"Todo el tr\xE1fico en la versi\xF3n nueva \u2014 finaliz\xE1 para retirar la anterior.","rollout.autoLabel":"Auto-avance","rollout.autoOff":"off","rollout.trafficHelp":"Arrastr\xE1 para mover el tr\xE1fico ahora; el auto-avance sube hasta 100%.","rollout.appLogs":"Logs de la aplicaci\xF3n","rollout.appLogsEmpty":"sin logs de la aplicaci\xF3n todav\xEDa\u2026","logs.title":"{app} \xB7 logs","logs.heading":"Logs","logs.filter":"filtrar\u2026","logs.live":"vivo","logs.refresh":"Refrescar","logs.updated":"actualizado {time}","logs.wrap":"Ajustar","logs.copyAll":"Copiar todo","logs.copied":"Copiado","logs.rangeLive":"En vivo","logs.range15m":"\xDAltimos 15m","logs.range1h":"\xDAltima 1h","logs.range6h":"\xDAltimas 6h","logs.range24h":"\xDAltimas 24h","logs.rangeCustom":"Personalizado\u2026","logs.apply":"Aplicar","logs.from":"Desde","logs.to":"Hasta","logs.empty":"sin l\xEDneas de log todav\xEDa\u2026","logs.noMatch":"nada coincide con el filtro","logs.count":"{count} l\xEDnea(s){scope}","logs.scopeSuffix":" \xB7 scope {scope}","logs.refreshFailed":"fall\xF3 el refresh: {message}","metrics.title":"{app} \xB7 m\xE9tricas de {scope}","metrics.heading":"M\xE9tricas","metrics.live":"vivo","metrics.loading":"cargando {window}\u2026","metrics.refreshFailed":"fall\xF3 el refresh: {message}","metrics.noData":"sin datapoints en esta ventana","metrics.avgMax":"prom {avg} \xB7 m\xE1x {max}","params.title":"{app} \xB7 par\xE1metros","params.heading":"Par\xE1metros","params.name":"Nombre","params.value":"Valor","params.secret":"Secreto","params.add":"+ Agregar","params.save":"Guardar cambios","params.applyNote":"Los valores cambiados aplican en el pr\xF3ximo deploy.","params.unavailable":"Los valores existentes no se pueden listar ac\xE1 \u2014 igual pod\xE9s agregar nuevos abajo.","params.saving":"Guardando {count} par\xE1metro(s)\u2026","params.saved":"Guardado \u2014 los valores aplican en el pr\xF3ximo deploy.","params.saveFailed":"Fall\xF3 el guardado: {message}","createApp.title":"Crear aplicaci\xF3n","createApp.name":"Nombre","createApp.namespace":"Namespace","createApp.repository":"Repositorio","createApp.newRepo":"Nuevo repositorio","createApp.importRepo":"Importar existente","createApp.template":"Template","createApp.noTemplates":"Sin templates disponibles","createApp.repoUrl":"URL del repositorio","createApp.editName":"Personalizar el nombre del repositorio","createApp.lockName":"Volver al nombre generado","createApp.importUrl":"URL del repositorio existente","createApp.monorepo":"Este repositorio es un monorepo","createApp.appPath":"Ruta de la aplicaci\xF3n dentro del repositorio","createApp.submit":"Crear aplicaci\xF3n","createApp.needName":"El nombre es obligatorio.","createApp.needNamespace":"Eleg\xED un namespace.","createApp.needTemplate":"Eleg\xED un template para el nuevo repositorio.","createApp.needImportUrl":"Ingres\xE1 la URL del repositorio a importar.","createApp.noBaseUrl":"Esta cuenta no tiene proveedor de git configurado \u2014 us\xE1 \u201CImportar existente\u201D.","createApp.creating":"Creando {name}\u2026 (vincula el repo, conecta CI \u2014 tarda unos segundos)","createApp.failed":"Fall\xF3: {message}","createApp.created":`{name} creada (#{id}, {status}).
829
+ Pushe\xE1 un commit para disparar el primer build y despu\xE9s deploy\xE1.`,"findApps.count":"{count} aplicaci\xF3n(es)","findApps.filter":"filtrar\u2026","findApps.across":"en {ns} namespace(s)","findApps.noMatch":"Nada coincide con el filtro.","findApps.loadMore":"Cargar {more} m\xE1s","findApps.hint":"Hac\xE9 clic en una aplicaci\xF3n para abrir su panel."},H_={en:F_,es:q_};function lf(e){return e?.structuredContent?._locale==="es"?"es":"en"}function uf(e){let r=H_[e];return(n,i)=>r[n].replace(/\{(\w+)\}/g,(t,o)=>i?.[o]!==void 0?String(i[o]):t)}var V_=sn(uf("en")),pf=V_.Provider;var df=e=>uf(e);function mf(e){return{render:function(r){ju(r,e)},unmount:function(){Tu(e)}}}function ff(e){let r=document.getElementById("root");r&&mf(r).render(e)}var B_=0;function h(e,r,n,i,t,o){r||(r={});var a,s,u=r;if("ref"in u)for(s in u={},r)s=="ref"?a=r[s]:u[s]=r[s];var p={type:e,props:u,key:n,ref:a,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--B_,__i:-1,__u:0,__source:t,__self:o};if(typeof e=="function"&&(a=e.defaultProps))for(s in a)u[s]===void 0&&(u[s]=a[s]);return U.vnode&&U.vnode(p),p}var J_={clock:{body:h(V,{children:[h("circle",{cx:"12",cy:"12",r:"10"}),h("polyline",{points:"12 6 12 12 16 14"})]})},play:{fill:!0,body:h("polygon",{points:"6 3 20 12 6 21 6 3"})},pause:{fill:!0,body:h(V,{children:[h("rect",{x:"6",y:"4",width:"4",height:"16",rx:"1"}),h("rect",{x:"14",y:"4",width:"4",height:"16",rx:"1"})]})},refresh:{body:h(V,{children:[h("path",{d:"M21 12a9 9 0 1 1-2.64-6.36"}),h("polyline",{points:"21 3 21 8 16 8"})]})},rocket:{body:h(V,{children:[h("path",{d:"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"}),h("path",{d:"m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"}),h("path",{d:"M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"}),h("path",{d:"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"})]})},logs:{body:h(V,{children:[h("path",{d:"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"}),h("polyline",{points:"14 2 14 8 20 8"}),h("line",{x1:"16",y1:"13",x2:"8",y2:"13"}),h("line",{x1:"16",y1:"17",x2:"8",y2:"17"}),h("line",{x1:"10",y1:"9",x2:"8",y2:"9"})]})},metrics:{body:h(V,{children:[h("polyline",{points:"22 7 13.5 15.5 8.5 10.5 2 17"}),h("polyline",{points:"16 7 22 7 22 13"})]})},lock:{body:h(V,{children:[h("rect",{x:"3",y:"11",width:"18",height:"11",rx:"2",ry:"2"}),h("path",{d:"M7 11V7a5 5 0 0 1 10 0v4"})]})},edit:{body:h("path",{d:"M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"})},copy:{body:h(V,{children:[h("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),h("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]})},check:{body:h("polyline",{points:"20 6 9 17 4 12"})},chevronDown:{body:h("polyline",{points:"6 9 12 15 18 9"})},chevronLeft:{body:h("polyline",{points:"15 18 9 12 15 6"})},chevronRight:{body:h("polyline",{points:"9 18 15 12 9 6"})},arrowLeft:{body:h(V,{children:[h("line",{x1:"19",y1:"12",x2:"5",y2:"12"}),h("polyline",{points:"12 19 5 12 12 5"})]})}},Cl=({name:e,size:r=14,className:n})=>{let i=J_[e];return h("svg",{className:["icon",n].filter(Boolean).join(" "),width:r,height:r,viewBox:"0 0 24 24",fill:i.fill?"currentColor":"none",stroke:i.fill?"none":"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",focusable:"false",children:i.body})};var Zl=({children:e})=>h("div",{className:"card",children:e}),W_=({children:e})=>h("div",{className:"row",children:e});var Ll=({tone:e,children:r})=>h("div",{className:`note${e?` ${e}`:""}`,children:r});var Qr=({variant:e,on:r,className:n,...i})=>h("button",{className:[e,r?"on":"",n].filter(Boolean).join(" "),...i}),Wt=({label:e,children:r})=>h("div",{className:"field",children:[h("div",{className:"label",children:e}),r]});var Q=({w:e="100%",h:r=12,r:n=6})=>h("div",{className:"skel",style:{width:e,height:r,borderRadius:n}}),gf=({variant:e})=>h(Zl,{children:[h(W_,{children:[h(Q,{w:170,h:16}),e!=="form"&&h(V,{children:[h("div",{className:"grow"}),h(Q,{w:110,h:28,r:8})]})]}),e==="list"&&h("div",{className:"skel-rows",children:[0,1,2,3,4,5].map(r=>h("div",{className:"skel-row",children:[h(Q,{w:8,h:8,r:999}),h(Q,{w:140,h:13}),h("div",{className:"grow"}),h(Q,{w:90,h:11})]},r))}),e==="panel"&&h(V,{children:[h("div",{className:"section",children:[h(Q,{w:64,h:10}),h("div",{style:{marginTop:10,display:"flex",flexDirection:"column",gap:10},children:[0,1].map(r=>h("div",{className:"skel-card",children:[h(Q,{w:r?"45%":"55%",h:14}),h("div",{style:{height:8}}),h(Q,{w:r?"70%":"85%",h:11})]},r))})]}),h("div",{className:"section",children:[h(Q,{w:64,h:10}),h("div",{style:{marginTop:10,display:"flex",gap:8},children:[0,1,2].map(r=>h(Q,{w:72,h:24,r:999},r))})]}),h("div",{className:"section",style:{display:"flex",gap:8},children:[h(Q,{w:132,h:34,r:9}),h(Q,{w:80,h:34,r:9})]})]}),e==="table"&&h("div",{className:"skel-rows",children:[0,1,2,3].map(r=>h("div",{className:"skel-row",children:[h(Q,{w:"30%",h:13}),h("div",{className:"grow"}),h(Q,{w:"42%",h:13}),h(Q,{w:18,h:13})]},r))}),e==="grid"&&h("div",{className:"skel-grid",children:[0,1,2,3].map(r=>h("div",{className:"skel-card",children:[h(Q,{w:"50%",h:10}),h("div",{style:{height:8}}),h(Q,{w:"35%",h:20}),h("div",{style:{height:8}}),h(Q,{w:"100%",h:40,r:8})]},r))}),e==="logs"&&h("div",{style:{marginTop:14},children:h(Q,{w:"100%",h:150,r:10})}),e==="form"&&h("div",{className:"skel-rows",children:[[0,1,2].map(r=>h("div",{children:[h(Q,{w:88,h:10}),h("div",{style:{height:7}}),h(Q,{w:"100%",h:32,r:8})]},r)),h(Q,{w:150,h:34,r:9})]})]});function K_(){let{result:e,call:r,brief:n}=cf("np-create-app"),i=Ge(()=>df(lf(e)),[e]),[t,o]=re([]),[a,s]=re([]),[u,p]=re(""),[m,l]=re(null),[b,v]=re("new"),[f,$]=re(null),[k,j]=re(""),[y,P]=re(!0),[O,ue]=re(""),[$e,Oe]=re(!1),[Se,be]=re(""),[Re,Ml]=re(!1),[hf,vf]=re(!1),[Fl,Ue]=re({text:""}),Kt=Me(E=>{let de=E?.structuredContent;if(de?.mode==="form"){let We=de.namespaces??[],di=de.templates??[];o(We),s(di),de.prefill?.name&&p(lt=>lt||de.prefill?.name||""),l(lt=>lt??de.prefill?.namespace_id??We[0]?.id??null),$(lt=>di.some(xf=>xf.id===lt)?lt:di[0]?.id??null);return}if(de?.application){let We=de.application;vf(!0),Ue({tone:We.status==="active"?"ok":void 0,text:i("createApp.created",{name:We.name,id:We.id,status:We.status})});return}let ql=sf(E);ql&&Ue({text:ql.slice(0,300)})},[i]);pt(()=>Kt(e),[e,Kt]);let _f=Me(async E=>{try{Kt(await r(Ii.applicationCreate,{namespace_id:E}))}catch{}},[Kt,r]),Yr=Ge(()=>t.find(E=>E.id===m),[t,m]),ct=Yr?.base_url??null,ui=Ge(()=>Yr&&u.trim()?`${rr(Yr.name)}-${rr(u)}`:rr(u),[Yr,u]),pi=y?ui:k||ui,bf=ct&&pi?`${ct}/${pi}`:"",yf=async()=>{if(Re)return;if(!u.trim())return Ue({tone:"bad",text:i("createApp.needName")});if(!m)return Ue({tone:"bad",text:i("createApp.needNamespace")});let E={name:u.trim(),namespace_id:m};if(b==="new"){if(!ct)return Ue({tone:"bad",text:i("createApp.noBaseUrl")});if(!f)return Ue({tone:"bad",text:i("createApp.needTemplate")});E.repository_url=bf,E.template_id=f}else{if(!O.trim())return Ue({tone:"bad",text:i("createApp.needImportUrl")});E.repository_url=O.trim(),$e&&Se.trim()&&(E.repository_app_path=Se.trim().replace(/^\/+|\/+$/g,""))}Ml(!0),Ue({text:i("createApp.creating",{name:u.trim()})});try{Kt(await r(Ii.applicationCreate,E)),n(`[create-app] user created application "${u.trim()}" from the widget.`)}catch(de){Ue({tone:"bad",text:i("createApp.failed",{message:Ou(de)})})}Ml(!1)};return e?h(pf,{value:i,children:h(Zl,{children:[h("div",{className:"title",style:{marginBottom:12},children:i("createApp.title")}),!hf&&h(V,{children:[h(Wt,{label:i("createApp.name"),children:h("input",{type:"text",placeholder:"my-service",autoComplete:"off",value:u,onChange:E=>p(E.target.value)})}),h(Wt,{label:i("createApp.namespace"),children:h("select",{value:m??"",onChange:E=>{let de=Number(E.target.value)||null;l(de),de&&_f(de)},children:t.map(E=>h("option",{value:E.id,children:[E.name,E.account?` \u2014 ${E.account}`:""]},E.id))})}),h("div",{className:"field",children:[h("div",{className:"label",children:i("createApp.repository")}),h("div",{className:"segmented",children:[h(Qr,{variant:"small",on:b==="new",className:"seg",onClick:()=>v("new"),children:i("createApp.newRepo")}),h(Qr,{variant:"small",on:b==="import",className:"seg",onClick:()=>v("import"),children:i("createApp.importRepo")})]})]}),b==="new"?h(V,{children:[h(Wt,{label:i("createApp.template"),children:h("select",{value:f??"",onChange:E=>$(Number(E.target.value)||null),children:[a.length===0&&h("option",{value:"",children:i("createApp.noTemplates")}),a.map(E=>h("option",{value:E.id,children:[E.name,E.tags?.length?` \xB7 ${E.tags.slice(0,2).join(", ")}`:""]},E.id))]})}),h("div",{className:"field",children:[h("div",{className:"label",children:i("createApp.repoUrl")}),ct?h("div",{className:"repo-url",children:[h("span",{className:"repo-base",title:ct,children:[ct,"/"]}),h("input",{type:"text",className:"grow mono",value:pi,disabled:y,spellCheck:!1,onChange:E=>j(rr(E.target.value))}),h(Qr,{variant:"small",className:"hasicon",title:i(y?"createApp.editName":"createApp.lockName"),"aria-label":i(y?"createApp.editName":"createApp.lockName"),on:!y,onClick:()=>{P(E=>(E&&j(ui),!E))},children:h(Cl,{name:y?"edit":"lock"})})]}):h(Ll,{tone:"bad",children:i("createApp.noBaseUrl")})]})]}):h(V,{children:[h(Wt,{label:i("createApp.importUrl"),children:h("input",{type:"text",className:"mono",placeholder:"https://github.com/org/existing-repo",autoComplete:"off",spellCheck:!1,value:O,onChange:E=>ue(E.target.value)})}),h("label",{className:"check-row",children:[h("input",{type:"checkbox",checked:$e,onChange:E=>Oe(E.target.checked)}),h("span",{children:i("createApp.monorepo")})]}),$e&&h(Wt,{label:i("createApp.appPath"),children:h("input",{type:"text",className:"mono",placeholder:"services/my-app",autoComplete:"off",spellCheck:!1,value:Se,onChange:E=>be(E.target.value)})})]}),h(Qr,{variant:"primary",disabled:Re,onClick:()=>{yf()},style:{marginTop:4},children:i("createApp.submit")})]}),h(Ll,{tone:Fl.tone,children:Fl.text})]})}):h(gf,{variant:"form"})}ff(h(K_,{}));})();
830
830
  </script></body></html>