setup-agent 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/host.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"host.js","names":[],"sources":["../src/host.ts"],"sourcesContent":["import { resource } from \"@assistant-ui/tap\";\nimport {\n StatewireReject,\n getStateHost,\n useStatewireCommands,\n useStatewireState,\n} from \"statewire/host\";\nimport {\n classifyChoiceAnswer,\n currentPlan,\n initialCheckoutState,\n isAgentPresent,\n isClosed,\n isValidModelAnswer,\n isValidEntryPointAnswer,\n isValidEntryPointInput,\n parseEntryPointOptions,\n parsePreviewUrl,\n} from \"./protocol\";\nimport type { Checkout } from \"./protocol\";\n\nconst reject = (reason: Checkout.RejectionReason, message: string) =>\n new StatewireReject(message, { payload: { reason } });\n\nconst useCheckoutHost = (restored: unknown) => {\n const [state] = useStatewireState<Checkout.State>(() => {\n const initial = initialCheckoutState();\n if (restored === undefined) return initial;\n const snapshot = restored as Partial<Checkout.State>;\n if (snapshot.version !== 2) return initial;\n return {\n ...initial,\n ...snapshot,\n agent: { ...initial.agent, ...snapshot.agent },\n };\n });\n\n const requireOpen = () => {\n if (state.createdAt === null) {\n throw reject(\"not-created\", \"the setup has not been created yet\");\n }\n if (isClosed(state)) {\n throw reject(\"closed\", `the setup is ${state.status}`);\n }\n };\n\n const requireStarted = () => {\n requireOpen();\n if (state.status === \"waiting\") {\n throw reject(\n \"planning-not-started\",\n 'ask the user to return to their browser and click \"Begin plan\"; wait with \"wait start\"',\n );\n }\n };\n\n const requireInstalling = () => {\n requireOpen();\n if (state.status !== \"installing\") {\n throw reject(\n \"plan-required\",\n \"steps run once the user has approved a plan; submit one with plan\",\n );\n }\n };\n\n const findStep = (stepId: string) => {\n const step = state.steps.find((candidate) => candidate.id === stepId);\n if (!step) throw reject(\"unknown-step\", `no step \"${stepId}\"`);\n return step;\n };\n\n const findInput = (inputId: string) => {\n const input = state.inputs.find((candidate) => candidate.id === inputId);\n if (!input) throw reject(\"unknown-input\", `no input \"${inputId}\"`);\n if (input.status !== \"open\") {\n throw reject(\"input-closed\", `input \"${inputId}\" is ${input.status}`);\n }\n return input;\n };\n\n const touchAgent = () => {\n state.agent.lastSeenAt = Date.now();\n state.agent.connected = true;\n };\n\n const ask = (seed: Checkout.InputSeed & { stepId?: string }) => {\n const kind = seed.kind ?? \"text\";\n const options =\n kind === \"entry-point\"\n ? parseEntryPointOptions(seed.options)\n : seed.options;\n if (kind === \"entry-point\" && !isValidEntryPointInput(seed)) {\n throw reject(\n \"invalid-input\",\n \"an entry-point input needs a prompt and 1–3 distinct options with descriptions, form factors, placements and triggers; at most one is recommended\",\n );\n }\n if (kind === \"product\") {\n if (!seed.product) {\n throw reject(\"invalid-input\", \"a product input names a product\");\n }\n if (state.products.some((product) => product.slug === seed.product)) {\n throw reject(\n \"invalid-input\",\n `\"${seed.product}\" is already part of this setup`,\n );\n }\n } else if (kind !== \"text\" && !seed.options?.length) {\n throw reject(\"invalid-input\", `a ${kind} input needs options`);\n }\n if (\n seed.multiple &&\n (kind !== \"choice\" ||\n seed.options?.some((option) => option.variants?.length))\n ) {\n throw reject(\n \"invalid-input\",\n \"only a choice whose options have no variants accepts several answers\",\n );\n }\n const unique = (ids: readonly string[]) => new Set(ids).size === ids.length;\n if (\n !unique(seed.options?.map((option) => option.id) ?? []) ||\n seed.options?.some(\n (option) =>\n !unique(option.variants?.map((variant) => variant.id) ?? []),\n )\n ) {\n throw reject(\"invalid-input\", \"option and variant ids must be unique\");\n }\n if (\n seed.options?.some(\n (option) =>\n option.id.includes(\":\") ||\n option.variants?.some((variant) => variant.id.includes(\":\")),\n )\n ) {\n throw reject(\n \"invalid-input\",\n 'option and variant ids cannot contain \":\", which separates them in an answer',\n );\n }\n if (\n seed.default !== undefined &&\n !seed.options?.some((option) => option.id === seed.default)\n ) {\n throw reject(\n \"invalid-input\",\n `no option \"${seed.default}\" to default to`,\n );\n }\n if (seed.stepId !== undefined) findStep(seed.stepId);\n const id = `q${state.inputs.length + 1}`;\n const stepId =\n seed.stepId ?? state.steps.find((step) => step.status === \"active\")?.id;\n state.inputs.push({\n id,\n phase: state.status,\n kind,\n ...(seed.preset !== undefined && { preset: seed.preset }),\n prompt: seed.prompt,\n ...(seed.placeholder !== undefined && { placeholder: seed.placeholder }),\n ...(options !== undefined && { options }),\n ...(seed.multiple && { multiple: true }),\n ...(kind === \"product\" && { product: seed.product }),\n ...(seed.default !== undefined && { default: seed.default }),\n ...(seed.help !== undefined && { help: seed.help }),\n optional: seed.optional ?? false,\n status: \"open\",\n ...(stepId !== undefined && { stepId }),\n createdAt: Date.now(),\n });\n return { inputId: id };\n };\n\n const dismissOpenInputs = () => {\n for (const input of state.inputs) {\n if (input.status === \"open\") {\n input.status = \"dismissed\";\n input.answeredAt = Date.now();\n }\n }\n };\n\n const log = (text: string, stepId?: string) => {\n state.log.push({\n id: `l${state.log.length + 1}`,\n role: \"agent\",\n phase: state.status,\n at: Date.now(),\n text,\n ...(stepId !== undefined && { stepId }),\n });\n };\n\n const updateStep = (\n step: Checkout.Step,\n status: Checkout.StepStatus,\n note?: string,\n ) => {\n const changed = step.status !== status;\n step.status = status;\n if (note !== undefined) step.note = note;\n if (changed && (status === \"done\" || status === \"skipped\")) {\n log(\n `${status === \"done\" ? \"Completed\" : \"Skipped\"}: ${step.title}${step.note ? `\\n\\n${step.note}` : \"\"}`,\n step.id,\n );\n }\n };\n\n const commands = useStatewireCommands<Checkout.Commands>({\n \"checkout/create\": ({ id, products, instructions }) => {\n if (state.id === id) {\n throw reject(\"already-created\", \"the setup already exists\");\n }\n const fresh = initialCheckoutState();\n if (!isAgentPresent(state)) state.agent = fresh.agent;\n state.id = id;\n state.status = fresh.status;\n delete state.completion;\n state.plans = fresh.plans;\n state.steps = fresh.steps;\n state.inputs = fresh.inputs;\n state.log = fresh.log;\n state.createdAt = Date.now();\n state.instructions = instructions?.trim() ?? \"\";\n state.products = products.map((product) => ({\n slug: product.slug,\n name: product.name,\n ...(product.guide !== undefined && { guide: product.guide }),\n }));\n },\n \"checkout/begin-plan\": () => {\n requireOpen();\n if (state.status === \"waiting\") state.status = \"planning\";\n },\n \"checkout/answer\": ({ inputId, answer, note }) => {\n requireOpen();\n const input = findInput(inputId);\n if (\n input.kind === \"choice\" &&\n classifyChoiceAnswer(input, answer) === \"invalid\"\n ) {\n throw reject(\n \"invalid-answer\",\n input.multiple\n ? `\"${answer}\" is not a JSON array of option ids`\n : `\"${answer}\" names an option without a valid variant`,\n );\n }\n if (\n input.kind === \"entry-point\" &&\n !isValidEntryPointAnswer(input, answer)\n ) {\n throw reject(\"invalid-answer\", \"an entry-point answer is an option id\");\n }\n if (input.kind === \"model\" && !isValidModelAnswer(input, answer)) {\n throw reject(\n \"invalid-answer\",\n \"a model answer is JSON with provider and model\",\n );\n }\n if (input.kind === \"product\") {\n throw reject(\n \"invalid-answer\",\n \"a product input is answered with checkout/add-product\",\n );\n }\n if (input.kind === \"text\" && answer.trim() === \"\") {\n throw reject(\"invalid-answer\", \"an answer cannot be empty\");\n }\n input.status = \"answered\";\n input.answeredAt = Date.now();\n input.answer = answer;\n if (note !== undefined && note.trim() !== \"\") input.note = note.trim();\n },\n \"checkout/add-product\": ({ inputId, product }) => {\n requireOpen();\n const input = findInput(inputId);\n if (input.kind !== \"product\" || input.product !== product.slug) {\n throw reject(\n \"invalid-answer\",\n `input \"${inputId}\" does not propose \"${product.slug}\"`,\n );\n }\n if (!state.products.some((entry) => entry.slug === product.slug)) {\n state.products.push({\n slug: product.slug,\n name: product.name,\n ...(product.guide !== undefined && { guide: product.guide }),\n });\n }\n input.status = \"answered\";\n input.answer = \"added\";\n input.answeredAt = Date.now();\n },\n \"checkout/message\": ({ text }) => {\n requireOpen();\n if (text.trim() === \"\")\n throw reject(\"empty-message\", \"a message cannot be empty\");\n const stepId = state.steps.find((step) => step.status === \"active\")?.id;\n state.log.push({\n id: `l${state.log.length + 1}`,\n role: \"user\",\n phase: state.status,\n ...(stepId !== undefined && { stepId }),\n at: Date.now(),\n text: text.trim(),\n });\n },\n \"agent/ack\": ({ messageId }) => {\n requireOpen();\n const message = state.log.find(\n (entry) => entry.id === messageId && entry.role === \"user\",\n );\n if (!message)\n throw reject(\"unknown-message\", `no user message \"${messageId}\"`);\n message.acknowledgedAt ??= Date.now();\n },\n \"checkout/dismiss\": ({ inputId }) => {\n requireOpen();\n const input = findInput(inputId);\n input.status = \"dismissed\";\n input.answeredAt = Date.now();\n },\n \"checkout/plan\": (params) => {\n requireOpen();\n const plan = currentPlan(state);\n if (plan === undefined) {\n throw reject(\"no-plan\", \"the agent has not proposed a plan yet\");\n }\n if (plan.status !== \"proposed\") {\n throw reject(\"plan-decided\", `the plan is already ${plan.status}`);\n }\n if (params.decision === \"approve\") {\n plan.status = \"approved\";\n plan.decidedAt = Date.now();\n state.status = \"installing\";\n return;\n }\n if (params.feedback.trim() === \"\") {\n throw reject(\"feedback-required\", \"say what should change\");\n }\n plan.status = \"changes-requested\";\n plan.decidedAt = Date.now();\n plan.feedback = params.feedback.trim();\n },\n \"checkout/cancel\": ({ id } = {}) => {\n if (state.createdAt === null || isClosed(state)) return;\n if (id !== undefined && id !== state.id) return;\n state.status = \"cancelled\";\n dismissOpenInputs();\n },\n \"checkout/finish\": () => {\n requireOpen();\n if (state.completion === undefined) {\n throw reject(\n \"finish-not-proposed\",\n \"the agent has not proposed to finish yet\",\n );\n }\n dismissOpenInputs();\n state.status = \"done\";\n log(\"Setup complete.\");\n },\n \"agent/intro\": ({ kind } = {}) => {\n requireOpen();\n if (state.agent.introducedAt === null) {\n state.agent.introducedAt = Date.now();\n }\n if (kind !== undefined) state.agent.kind = kind;\n },\n \"agent/hello\": ({ cwd, kind } = {}) => {\n touchAgent();\n if (cwd !== undefined) state.agent.cwd = cwd;\n if (kind !== undefined) state.agent.kind = kind;\n },\n \"agent/heartbeat\": () => {\n touchAgent();\n },\n \"agent/bye\": () => {\n state.agent.connected = false;\n },\n \"agent/plan\": ({ markdown }) => {\n requireStarted();\n touchAgent();\n if (markdown.trim() === \"\") {\n throw reject(\"empty-plan\", \"the plan is empty\");\n }\n if (state.status === \"installing\") {\n throw reject(\"plan-decided\", \"the plan is already approved\");\n }\n const revision = state.plans.length + 1;\n state.plans.push({\n revision,\n markdown: markdown.trim(),\n status: \"proposed\",\n submittedAt: Date.now(),\n });\n return { revision };\n },\n \"agent/add-step\": ({ title, detail, product, active }) => {\n requireInstalling();\n if (product !== undefined && product.trim() === \"\") {\n throw reject(\n \"invalid-input\",\n \"a step's product identifier cannot be empty\",\n );\n }\n const id = `s${state.steps.length + 1}`;\n state.steps.push({\n id,\n title,\n ...(detail !== undefined && { detail }),\n status: active ? \"active\" : \"pending\",\n ...(product !== undefined && { product }),\n createdAt: Date.now(),\n });\n return { stepId: id };\n },\n \"agent/step\": ({ stepId, status, note }) => {\n requireInstalling();\n const step = findStep(stepId);\n updateStep(step, status, note);\n },\n \"agent/ask\": (seed) => {\n requireStarted();\n touchAgent();\n return ask(seed);\n },\n \"agent/log\": ({ text }) => {\n requireOpen();\n touchAgent();\n const stepId = state.steps.find((step) => step.status === \"active\")?.id;\n log(text, stepId);\n },\n \"agent/done\": ({ summary, preview } = {}) => {\n requireInstalling();\n const previewUrl = parsePreviewUrl(preview?.trim());\n if (preview !== undefined && !previewUrl) {\n throw reject(\n \"invalid-preview\",\n \"a preview is an http URL on localhost, such as http://localhost:3000\",\n );\n }\n touchAgent();\n for (const step of state.steps) {\n if (step.status === \"pending\" || step.status === \"active\") {\n updateStep(step, \"done\");\n }\n }\n log(summary?.trim() || \"Everything is installed.\");\n state.completion = {\n proposedAt: Date.now(),\n ...(previewUrl && { preview: previewUrl.href }),\n };\n },\n });\n\n const source = getStateHost(state)!;\n return {\n state,\n commands,\n snapshot: source.snapshot,\n subscribe: (listener: () => void) => {\n source.setOnChange(listener);\n return () => source.setOnChange(null);\n },\n };\n};\n\n/** The setup statewire host; pass the durable object's restored snapshot. */\nexport const CheckoutHost = (restored?: unknown) =>\n resource(useCheckoutHost)(restored);\n\nexport type { Checkout } from \"./protocol\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"host.js","names":[],"sources":["../src/host.ts"],"sourcesContent":["import { resource } from \"@assistant-ui/tap\";\nimport {\n StatewireReject,\n getStateHost,\n useStatewireCommands,\n useStatewireState,\n} from \"statewire/host\";\nimport {\n classifyChoiceAnswer,\n currentPlan,\n initialCheckoutState,\n isAgentPresent,\n isClosed,\n isValidModelAnswer,\n isValidEntryPointAnswer,\n isValidEntryPointInput,\n parseEntryPointOptions,\n parsePreviewUrl,\n} from \"./protocol\";\nimport type { Checkout } from \"./protocol\";\n\nconst reject = (reason: Checkout.RejectionReason, message: string) =>\n new StatewireReject(message, { payload: { reason } });\n\nconst useCheckoutHost = (restored: unknown) => {\n const [state] = useStatewireState<Checkout.State>(() => {\n const initial = initialCheckoutState();\n if (restored === undefined) return initial;\n const snapshot = restored as Partial<Checkout.State>;\n if (snapshot.version !== 2) return initial;\n return {\n ...initial,\n ...snapshot,\n agent: { ...initial.agent, ...snapshot.agent },\n };\n });\n\n const requireOpen = () => {\n if (state.createdAt === null) {\n throw reject(\"not-created\", \"the setup has not been created yet\");\n }\n if (isClosed(state)) {\n throw reject(\"closed\", `the setup is ${state.status}`);\n }\n };\n\n const requireStarted = () => {\n requireOpen();\n if (state.status === \"waiting\") {\n throw reject(\n \"planning-not-started\",\n 'ask the user to return to their browser and click \"Begin plan\"; wait with \"wait start\"',\n );\n }\n };\n\n const requireInstalling = () => {\n requireOpen();\n if (state.status !== \"installing\") {\n throw reject(\n \"plan-required\",\n \"steps run once the user has approved a plan; submit one with plan\",\n );\n }\n };\n\n const findStep = (stepId: string) => {\n const step = state.steps.find((candidate) => candidate.id === stepId);\n if (!step) throw reject(\"unknown-step\", `no step \"${stepId}\"`);\n return step;\n };\n\n const findInput = (inputId: string) => {\n const input = state.inputs.find((candidate) => candidate.id === inputId);\n if (!input) throw reject(\"unknown-input\", `no input \"${inputId}\"`);\n if (input.status !== \"open\") {\n throw reject(\"input-closed\", `input \"${inputId}\" is ${input.status}`);\n }\n return input;\n };\n\n const touchAgent = () => {\n state.agent.lastSeenAt = Date.now();\n state.agent.connected = true;\n };\n\n const ask = (seed: Checkout.InputSeed & { stepId?: string }) => {\n const kind = seed.kind ?? \"text\";\n if (\n seed.redeemKeyHash !== undefined &&\n (kind !== \"model\" || !/^[0-9a-f]{64}$/.test(seed.redeemKeyHash))\n ) {\n throw reject(\"invalid-input\", \"invalid model redeem key hash\");\n }\n const options =\n kind === \"entry-point\"\n ? parseEntryPointOptions(seed.options)\n : seed.options;\n if (kind === \"entry-point\" && !isValidEntryPointInput(seed)) {\n throw reject(\n \"invalid-input\",\n \"an entry-point input needs a prompt and 1–3 distinct options with descriptions, form factors, placements and triggers; at most one is recommended\",\n );\n }\n if (kind === \"product\") {\n if (!seed.product) {\n throw reject(\"invalid-input\", \"a product input names a product\");\n }\n if (state.products.some((product) => product.slug === seed.product)) {\n throw reject(\n \"invalid-input\",\n `\"${seed.product}\" is already part of this setup`,\n );\n }\n } else if (kind !== \"text\" && !seed.options?.length) {\n throw reject(\"invalid-input\", `a ${kind} input needs options`);\n }\n if (\n seed.multiple &&\n (kind !== \"choice\" ||\n seed.options?.some((option) => option.variants?.length))\n ) {\n throw reject(\n \"invalid-input\",\n \"only a choice whose options have no variants accepts several answers\",\n );\n }\n const unique = (ids: readonly string[]) => new Set(ids).size === ids.length;\n if (\n !unique(seed.options?.map((option) => option.id) ?? []) ||\n seed.options?.some(\n (option) =>\n !unique(option.variants?.map((variant) => variant.id) ?? []),\n )\n ) {\n throw reject(\"invalid-input\", \"option and variant ids must be unique\");\n }\n if (\n seed.options?.some(\n (option) =>\n option.id.includes(\":\") ||\n option.variants?.some((variant) => variant.id.includes(\":\")),\n )\n ) {\n throw reject(\n \"invalid-input\",\n 'option and variant ids cannot contain \":\", which separates them in an answer',\n );\n }\n if (\n seed.default !== undefined &&\n !seed.options?.some((option) => option.id === seed.default)\n ) {\n throw reject(\n \"invalid-input\",\n `no option \"${seed.default}\" to default to`,\n );\n }\n if (seed.stepId !== undefined) findStep(seed.stepId);\n const id = `q${state.inputs.length + 1}`;\n const stepId =\n seed.stepId ?? state.steps.find((step) => step.status === \"active\")?.id;\n state.inputs.push({\n id,\n phase: state.status,\n kind,\n ...(seed.preset !== undefined && { preset: seed.preset }),\n prompt: seed.prompt,\n ...(seed.placeholder !== undefined && { placeholder: seed.placeholder }),\n ...(options !== undefined && { options }),\n ...(seed.multiple && { multiple: true }),\n ...(kind === \"product\" && { product: seed.product }),\n ...(seed.default !== undefined && { default: seed.default }),\n ...(seed.help !== undefined && { help: seed.help }),\n ...(seed.redeemKeyHash !== undefined && {\n redeemKeyHash: seed.redeemKeyHash,\n }),\n optional: seed.optional ?? false,\n status: \"open\",\n ...(stepId !== undefined && { stepId }),\n createdAt: Date.now(),\n });\n return { inputId: id };\n };\n\n const dismissOpenInputs = () => {\n for (const input of state.inputs) {\n if (input.status === \"open\") {\n input.status = \"dismissed\";\n input.answeredAt = Date.now();\n }\n }\n };\n\n const log = (text: string, stepId?: string) => {\n state.log.push({\n id: `l${state.log.length + 1}`,\n role: \"agent\",\n phase: state.status,\n at: Date.now(),\n text,\n ...(stepId !== undefined && { stepId }),\n });\n };\n\n const updateStep = (\n step: Checkout.Step,\n status: Checkout.StepStatus,\n note?: string,\n ) => {\n const changed = step.status !== status;\n step.status = status;\n if (note !== undefined) step.note = note;\n if (changed && (status === \"done\" || status === \"skipped\")) {\n log(\n `${status === \"done\" ? \"Completed\" : \"Skipped\"}: ${step.title}${step.note ? `\\n\\n${step.note}` : \"\"}`,\n step.id,\n );\n }\n };\n\n const commands = useStatewireCommands<Checkout.Commands>({\n \"checkout/create\": ({ id, products, instructions }) => {\n if (state.id === id) {\n throw reject(\"already-created\", \"the setup already exists\");\n }\n const fresh = initialCheckoutState();\n if (!isAgentPresent(state)) state.agent = fresh.agent;\n state.id = id;\n state.status = fresh.status;\n delete state.completion;\n state.plans = fresh.plans;\n state.steps = fresh.steps;\n state.inputs = fresh.inputs;\n state.log = fresh.log;\n state.createdAt = Date.now();\n state.instructions = instructions?.trim() ?? \"\";\n state.products = products.map((product) => ({\n slug: product.slug,\n name: product.name,\n ...(product.guide !== undefined && { guide: product.guide }),\n }));\n },\n \"checkout/begin-plan\": () => {\n requireOpen();\n if (state.status === \"waiting\") state.status = \"planning\";\n },\n \"checkout/answer\": ({ inputId, answer, note }) => {\n requireOpen();\n const input = findInput(inputId);\n if (\n input.kind === \"choice\" &&\n classifyChoiceAnswer(input, answer) === \"invalid\"\n ) {\n throw reject(\n \"invalid-answer\",\n input.multiple\n ? `\"${answer}\" is not a JSON array of option ids`\n : `\"${answer}\" names an option without a valid variant`,\n );\n }\n if (\n input.kind === \"entry-point\" &&\n !isValidEntryPointAnswer(input, answer)\n ) {\n throw reject(\"invalid-answer\", \"an entry-point answer is an option id\");\n }\n if (input.kind === \"model\" && !isValidModelAnswer(input, answer)) {\n throw reject(\n \"invalid-answer\",\n \"a model answer is JSON with provider and model\",\n );\n }\n if (input.kind === \"product\") {\n throw reject(\n \"invalid-answer\",\n \"a product input is answered with checkout/add-product\",\n );\n }\n if (input.kind === \"text\" && answer.trim() === \"\") {\n throw reject(\"invalid-answer\", \"an answer cannot be empty\");\n }\n input.status = \"answered\";\n input.answeredAt = Date.now();\n input.answer = answer;\n if (note !== undefined && note.trim() !== \"\") input.note = note.trim();\n },\n \"checkout/add-product\": ({ inputId, product }) => {\n requireOpen();\n const input = findInput(inputId);\n if (input.kind !== \"product\" || input.product !== product.slug) {\n throw reject(\n \"invalid-answer\",\n `input \"${inputId}\" does not propose \"${product.slug}\"`,\n );\n }\n if (!state.products.some((entry) => entry.slug === product.slug)) {\n state.products.push({\n slug: product.slug,\n name: product.name,\n ...(product.guide !== undefined && { guide: product.guide }),\n });\n }\n input.status = \"answered\";\n input.answer = \"added\";\n input.answeredAt = Date.now();\n },\n \"checkout/message\": ({ text }) => {\n requireOpen();\n if (text.trim() === \"\")\n throw reject(\"empty-message\", \"a message cannot be empty\");\n const stepId = state.steps.find((step) => step.status === \"active\")?.id;\n state.log.push({\n id: `l${state.log.length + 1}`,\n role: \"user\",\n phase: state.status,\n ...(stepId !== undefined && { stepId }),\n at: Date.now(),\n text: text.trim(),\n });\n },\n \"agent/ack\": ({ messageId }) => {\n requireOpen();\n const message = state.log.find(\n (entry) => entry.id === messageId && entry.role === \"user\",\n );\n if (!message)\n throw reject(\"unknown-message\", `no user message \"${messageId}\"`);\n message.acknowledgedAt ??= Date.now();\n },\n \"checkout/dismiss\": ({ inputId }) => {\n requireOpen();\n const input = findInput(inputId);\n input.status = \"dismissed\";\n input.answeredAt = Date.now();\n },\n \"checkout/plan\": (params) => {\n requireOpen();\n const plan = currentPlan(state);\n if (plan === undefined) {\n throw reject(\"no-plan\", \"the agent has not proposed a plan yet\");\n }\n if (\n (params.id !== undefined && params.id !== state.id) ||\n (params.revision !== undefined && params.revision !== plan.revision)\n ) {\n throw reject(\n \"stale-plan\",\n \"review the current setup plan before deciding\",\n );\n }\n if (plan.status !== \"proposed\") {\n throw reject(\"plan-decided\", `the plan is already ${plan.status}`);\n }\n if (params.decision === \"approve\") {\n plan.status = \"approved\";\n plan.decidedAt = Date.now();\n state.status = \"installing\";\n return;\n }\n if (params.feedback.trim() === \"\") {\n throw reject(\"feedback-required\", \"say what should change\");\n }\n plan.status = \"changes-requested\";\n plan.decidedAt = Date.now();\n plan.feedback = params.feedback.trim();\n },\n \"checkout/cancel\": ({ id } = {}) => {\n if (state.createdAt === null || isClosed(state)) return;\n if (id !== undefined && id !== state.id) return;\n state.status = \"cancelled\";\n dismissOpenInputs();\n },\n \"checkout/finish\": () => {\n requireOpen();\n if (state.completion === undefined) {\n throw reject(\n \"finish-not-proposed\",\n \"the agent has not proposed to finish yet\",\n );\n }\n dismissOpenInputs();\n state.status = \"done\";\n log(\"Setup complete.\");\n },\n \"agent/intro\": ({ kind } = {}) => {\n requireOpen();\n if (state.agent.introducedAt === null) {\n state.agent.introducedAt = Date.now();\n }\n if (kind !== undefined) state.agent.kind = kind;\n },\n \"agent/hello\": ({ cwd, kind } = {}) => {\n touchAgent();\n if (cwd !== undefined) state.agent.cwd = cwd;\n if (kind !== undefined) state.agent.kind = kind;\n },\n \"agent/heartbeat\": () => {\n touchAgent();\n },\n \"agent/bye\": () => {\n state.agent.connected = false;\n },\n \"agent/plan\": ({ markdown }) => {\n requireStarted();\n touchAgent();\n if (markdown.trim() === \"\") {\n throw reject(\"empty-plan\", \"the plan is empty\");\n }\n if (state.status === \"installing\") {\n throw reject(\"plan-decided\", \"the plan is already approved\");\n }\n const revision = state.plans.length + 1;\n state.plans.push({\n revision,\n markdown: markdown.trim(),\n status: \"proposed\",\n submittedAt: Date.now(),\n });\n return { revision };\n },\n \"agent/add-step\": ({ title, detail, product, active }) => {\n requireInstalling();\n if (product !== undefined && product.trim() === \"\") {\n throw reject(\n \"invalid-input\",\n \"a step's product identifier cannot be empty\",\n );\n }\n const id = `s${state.steps.length + 1}`;\n state.steps.push({\n id,\n title,\n ...(detail !== undefined && { detail }),\n status: active ? \"active\" : \"pending\",\n ...(product !== undefined && { product }),\n createdAt: Date.now(),\n });\n return { stepId: id };\n },\n \"agent/step\": ({ stepId, status, note }) => {\n requireInstalling();\n const step = findStep(stepId);\n updateStep(step, status, note);\n },\n \"agent/ask\": (seed) => {\n requireStarted();\n touchAgent();\n return ask(seed);\n },\n \"agent/log\": ({ text }) => {\n requireOpen();\n touchAgent();\n const stepId = state.steps.find((step) => step.status === \"active\")?.id;\n log(text, stepId);\n },\n \"agent/done\": ({ summary, preview } = {}) => {\n requireInstalling();\n const previewUrl = parsePreviewUrl(preview?.trim());\n if (preview !== undefined && !previewUrl) {\n throw reject(\n \"invalid-preview\",\n \"a preview is an http URL on localhost, such as http://localhost:3000\",\n );\n }\n touchAgent();\n for (const step of state.steps) {\n if (step.status === \"pending\" || step.status === \"active\") {\n updateStep(step, \"done\");\n }\n }\n log(summary?.trim() || \"Everything is installed.\");\n state.completion = {\n proposedAt: Date.now(),\n ...(previewUrl && { preview: previewUrl.href }),\n };\n },\n });\n\n const source = getStateHost(state)!;\n return {\n state,\n commands,\n snapshot: source.snapshot,\n subscribe: (listener: () => void) => {\n source.setOnChange(listener);\n return () => source.setOnChange(null);\n },\n };\n};\n\n/** The setup statewire host; pass the durable object's restored snapshot. */\nexport const CheckoutHost = (restored?: unknown) =>\n resource(useCheckoutHost)(restored);\n\nexport type { Checkout } from \"./protocol\";\n"],"mappings":"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"}
package/dist/presets.js CHANGED
@@ -1,4 +1,4 @@
1
- //#region src/presets.ts
1
+ // src/presets.ts
2
2
  const TYPESCRIPT = {
3
3
  id: "typescript",
4
4
  label: "TypeScript"
@@ -170,7 +170,6 @@ const presetInput = (id, overrides = {}) => {
170
170
  ...overrides.stepId !== void 0 && { stepId: overrides.stepId }
171
171
  };
172
172
  };
173
- //#endregion
174
173
  export { INPUT_PRESETS, isPresetId, presetInput };
175
174
 
176
175
  //# sourceMappingURL=presets.js.map
@@ -86,6 +86,7 @@ export declare namespace Checkout {
86
86
  product?: string;
87
87
  default?: string;
88
88
  help?: InputHelp;
89
+ redeemKeyHash?: string;
89
90
  optional: boolean;
90
91
  status: InputStatus;
91
92
  answer?: string;
@@ -171,14 +172,20 @@ export declare namespace Checkout {
171
172
  product?: string;
172
173
  default?: string;
173
174
  help?: InputHelp;
175
+ redeemKeyHash?: string;
174
176
  optional?: boolean;
175
177
  };
176
178
  type PlanDecision = {
179
+ /** The setup the browser reviewed; omitted by legacy clients. */
180
+ id?: string;
181
+ /** The plan revision the browser reviewed; omitted by legacy clients. */
182
+ revision?: number;
183
+ } & ({
177
184
  decision: "approve";
178
185
  } | {
179
186
  decision: "revise";
180
187
  feedback: string;
181
- };
188
+ });
182
189
  type Commands = {
183
190
  "checkout/create": (params: {
184
191
  id: string;
@@ -251,7 +258,7 @@ export declare namespace Checkout {
251
258
  preview?: string;
252
259
  }) => void;
253
260
  };
254
- type RejectionReason = "already-created" | "not-created" | "closed" | "planning-not-started" | "plan-required" | "no-plan" | "plan-decided" | "finish-not-proposed" | "feedback-required" | "empty-plan" | "unknown-step" | "unknown-product" | "unknown-input" | "input-closed" | "invalid-input" | "invalid-answer" | "invalid-preview" | "empty-message" | "unknown-message";
261
+ type RejectionReason = "already-created" | "not-created" | "closed" | "planning-not-started" | "plan-required" | "no-plan" | "plan-decided" | "stale-plan" | "finish-not-proposed" | "feedback-required" | "empty-plan" | "unknown-step" | "unknown-product" | "unknown-input" | "input-closed" | "invalid-input" | "invalid-answer" | "invalid-preview" | "empty-message" | "unknown-message";
255
262
  }
256
263
  export declare const AGENT_PRESENCE_MS = 15000;
257
264
  export declare const AGENT_HEARTBEAT_MS = 5000;
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
package/dist/protocol.js CHANGED
@@ -1,4 +1,4 @@
1
- //#region src/protocol.ts
1
+ // src/protocol.ts
2
2
  const AGENT_PRESENCE_MS = 15e3;
3
3
  const AGENT_HEARTBEAT_MS = 5e3;
4
4
  const initialCheckoutState = () => ({
@@ -209,7 +209,6 @@ const stepProgress = (state) => ({
209
209
  total: state.steps.length,
210
210
  done: state.steps.filter((step) => step.status === "done" || step.status === "skipped").length
211
211
  });
212
- //#endregion
213
212
  export { AGENT_HEARTBEAT_MS, AGENT_PRESENCE_MS, OPTION_ICONS, classifyChoiceAnswer, currentPlan, finishProposed, followedUpSinceProposal, initialCheckoutState, isAgentPresent, isClosed, isOptionIcon, isValidEntryPointAnswer, isValidEntryPointInput, isValidModelAnswer, openInputs, parseChoiceAnswer, parseEntryPointOptions, parseModelAnswer, parseMultipleAnswer, parsePreviewUrl, planNeedsReview, stepProgress };
214
213
 
215
214
  //# sourceMappingURL=protocol.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","names":[],"sources":["../src/protocol.ts"],"sourcesContent":["export namespace Checkout {\n export type StepStatus =\n | \"pending\"\n | \"active\"\n | \"done\"\n | \"skipped\"\n | \"blocked\";\n\n /** A unit of install work the agent declared; the catalog seeds none. */\n export type Step = {\n id: string;\n title: string;\n detail?: string;\n status: StepStatus;\n note?: string;\n /** The product this step belongs to, when the agent said. */\n product?: string;\n createdAt: number;\n };\n\n export type Product = {\n slug: string;\n name: string;\n /** The install reference the agent fetches while planning. */\n guide?: string;\n };\n\n export type InputStatus = \"open\" | \"answered\" | \"dismissed\";\n\n /**\n * product: the agent proposes adding a product to this checkout, such as one\n * another product depends on. The browser owns the catalog, so it answers\n * with `checkout/add-product`; dismissing the input declines.\n */\n export type InputKind =\n | \"text\"\n | \"choice\"\n | \"model\"\n | \"product\"\n | \"entry-point\";\n\n export type EntryPoint = {\n formFactor: \"modal\" | \"sidebar\" | \"full-page\";\n placement: string;\n trigger: string;\n recommended?: boolean;\n };\n\n export type EntryPointOption = {\n id: string;\n label: string;\n description: string;\n entryPoint: EntryPoint;\n };\n\n export type ChoiceVariant = { id: string; label: string };\n\n export type ChoiceOption = {\n id: string;\n label: string;\n description?: string;\n /** A name from OPTION_ICONS, or the key of a brand mark on a preset option; unknown keys render without one. */\n icon?: string;\n /** A second pick under this option, such as the language of a framework. */\n variants?: ChoiceVariant[];\n entryPoint?: EntryPoint;\n };\n\n /** A short nudge for users who need help choosing, with a longer guide to link to. */\n export type InputHelp = { summary: string; href?: string };\n\n /**\n * The answer to a model input, stored as JSON text. The API key itself is\n * never part of it: the browser deposits it with the checkout and the\n * agent's `env` command writes it straight to a file.\n */\n export type ModelAnswer = {\n provider: string;\n model: string;\n reasoningEffort?: \"low\" | \"medium\" | \"high\";\n };\n\n /**\n * A choice answer is an option id, `<option>:<variant>` when the option has\n * variants, or the user's own text when none of the options fit; a multiple\n * choice answers a JSON array of those. A model answer is a JSON-encoded\n * ModelAnswer whose provider is one of the options.\n */\n export type Input = {\n phase: Status;\n id: string;\n kind: InputKind;\n /** The standard input this was built from, when it was. */\n preset?: string;\n prompt: string;\n placeholder?: string;\n options?: ChoiceOption[];\n /** The user may pick any number of options; the answer is a JSON array. */\n multiple?: true;\n /** The slug a product input proposes. */\n product?: string;\n default?: string;\n help?: InputHelp;\n optional: boolean;\n status: InputStatus;\n answer?: string;\n /** A remark the user attached to the answer. */\n note?: string;\n stepId?: string;\n createdAt: number;\n answeredAt?: number;\n };\n\n export type LogEntry = {\n phase: Status;\n id: string;\n role: \"agent\" | \"user\";\n acknowledgedAt?: number;\n at: number;\n text: string;\n /** The step that was active when the line was posted; none while planning. */\n stepId?: string;\n };\n\n export type PlanStatus = \"proposed\" | \"approved\" | \"changes-requested\";\n\n /** One revision of the agent's plan. Markdown the browser renders. */\n export type Plan = {\n revision: number;\n markdown: string;\n status: PlanStatus;\n submittedAt: number;\n decidedAt?: number;\n /** What the user asked to change, when they did. */\n feedback?: string;\n };\n\n /**\n * waiting: no agent has joined. planning: the agent investigates and\n * proposes a plan. installing: the plan is approved and steps run.\n */\n export type Status =\n | \"waiting\"\n | \"planning\"\n | \"installing\"\n | \"done\"\n | \"cancelled\";\n\n /**\n * The agent's proposal to close the checkout. Only the user closes it, and\n * they may keep messaging the agent instead; a later `done` renews it.\n * `preview` is the loopback URL of a dev server the agent left running for\n * the user to try before they close.\n */\n export type Completion = { proposedAt: number; preview?: string };\n\n export type State = {\n version: 2;\n /** The id the browser gave the current checkout; a create with another id replaces it on the same link. */\n id: string | null;\n status: Status;\n completion?: Completion;\n createdAt: number | null;\n products: Product[];\n instructions: string;\n agent: {\n lastSeenAt: number | null;\n /** False once the agent's stream said goodbye; heartbeats set it again. */\n connected: boolean;\n cwd: string | null;\n /** The coding agent that ran the command, as the CLI detected it from its environment. */\n kind: string | null;\n /** When the command was first run against this checkout, before the agent joined the stream. */\n introducedAt: number | null;\n };\n /** Every revision in order; the last one is current. */\n plans: Plan[];\n steps: Step[];\n inputs: Input[];\n log: LogEntry[];\n };\n\n export type ProductSeed = { slug: string; name: string; guide?: string };\n\n export type InputSeed = {\n kind?: InputKind;\n preset?: string;\n prompt: string;\n placeholder?: string;\n options?: ChoiceOption[];\n multiple?: true;\n product?: string;\n default?: string;\n help?: InputHelp;\n optional?: boolean;\n };\n\n export type PlanDecision =\n | { decision: \"approve\" }\n | { decision: \"revise\"; feedback: string };\n\n export type Commands = {\n \"checkout/create\": (params: {\n id: string;\n products: ProductSeed[];\n instructions?: string;\n }) => void;\n \"checkout/begin-plan\": () => void;\n \"checkout/answer\": (params: {\n inputId: string;\n answer: string;\n note?: string;\n }) => void;\n \"checkout/add-product\": (params: {\n inputId: string;\n product: ProductSeed;\n }) => void;\n \"checkout/message\": (params: { text: string }) => void;\n \"agent/ack\": (params: { messageId: string }) => void;\n \"checkout/dismiss\": (params: { inputId: string }) => void;\n \"checkout/plan\": (params: PlanDecision) => void;\n /** A cancel that names another checkout than the current one is a no-op. */\n \"checkout/cancel\": (params?: { id?: string }) => void;\n \"checkout/finish\": () => void;\n \"agent/intro\": (params: { kind?: string }) => void;\n \"agent/hello\": (params: { cwd?: string; kind?: string }) => void;\n \"agent/heartbeat\": () => void;\n \"agent/bye\": () => void;\n \"agent/plan\": (params: { markdown: string }) => { revision: number };\n \"agent/add-step\": (params: {\n title: string;\n detail?: string;\n product?: string;\n /** Start the step in the same call. */\n active?: boolean;\n }) => { stepId: string };\n \"agent/step\": (params: {\n stepId: string;\n status: StepStatus;\n note?: string;\n }) => void;\n \"agent/ask\": (params: InputSeed & { stepId?: string }) => {\n inputId: string;\n };\n \"agent/log\": (params: { text: string }) => void;\n \"agent/done\": (params?: { summary?: string; preview?: string }) => void;\n };\n\n export type RejectionReason =\n | \"already-created\"\n | \"not-created\"\n | \"closed\"\n | \"planning-not-started\"\n | \"plan-required\"\n | \"no-plan\"\n | \"plan-decided\"\n | \"finish-not-proposed\"\n | \"feedback-required\"\n | \"empty-plan\"\n | \"unknown-step\"\n | \"unknown-product\"\n | \"unknown-input\"\n | \"input-closed\"\n | \"invalid-input\"\n | \"invalid-answer\"\n | \"invalid-preview\"\n | \"empty-message\"\n | \"unknown-message\";\n}\n\nexport const AGENT_PRESENCE_MS = 15_000;\nexport const AGENT_HEARTBEAT_MS = 5_000;\n\nexport const initialCheckoutState = (): Checkout.State => ({\n version: 2,\n id: null,\n status: \"waiting\",\n createdAt: null,\n products: [],\n instructions: \"\",\n agent: {\n lastSeenAt: null,\n connected: false,\n cwd: null,\n kind: null,\n introducedAt: null,\n },\n plans: [],\n steps: [],\n inputs: [],\n log: [],\n});\n\nexport const isAgentPresent = (state: Checkout.State, now = Date.now()) =>\n state.agent.connected &&\n state.agent.lastSeenAt !== null &&\n now - state.agent.lastSeenAt < AGENT_PRESENCE_MS;\n\nexport const isClosed = (state: Checkout.State) =>\n state.status === \"done\" || state.status === \"cancelled\";\n\n/** True while the agent's proposal to close waits for the user. */\nexport const finishProposed = (state: Checkout.State) =>\n !isClosed(state) && state.completion !== undefined;\n\n/** True while a message the user sent after the agent proposed to close still waits for the agent. */\nexport const followedUpSinceProposal = (state: Checkout.State) => {\n const proposedAt = state.completion?.proposedAt;\n return (\n proposedAt !== undefined &&\n state.log.some(\n (entry) =>\n entry.role === \"user\" &&\n entry.at > proposedAt &&\n entry.acknowledgedAt === undefined,\n )\n );\n};\n\nconst LOOPBACK_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"[::1]\"]);\n\n/**\n * The URL a preview names, or `undefined` unless it is an http(s) URL on this\n * machine's loopback interface. The browser opens it, so nothing else passes.\n */\nexport const parsePreviewUrl = (value: string | undefined) => {\n if (!value) return undefined;\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n return undefined;\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") return undefined;\n if (url.username !== \"\" || url.password !== \"\") return undefined;\n const loopback =\n LOOPBACK_HOSTS.has(url.hostname) || url.hostname.endsWith(\".localhost\");\n return loopback ? url : undefined;\n};\n\nexport const openInputs = (state: Checkout.State) =>\n state.inputs.filter((input) => input.status === \"open\");\n\n/** The current plan revision, or `undefined` before the agent proposed one. */\nexport const currentPlan = (state: Checkout.State): Checkout.Plan | undefined =>\n state.plans.at(-1);\n\n/** True while a proposed plan waits for the user's decision. */\nexport const planNeedsReview = (state: Checkout.State) =>\n !isClosed(state) && currentPlan(state)?.status === \"proposed\";\n\n/** The icons an agent can put on its own options, by name. */\nexport const OPTION_ICONS = [\n \"code\",\n \"terminal\",\n \"braces\",\n \"git-branch\",\n \"package\",\n \"database\",\n \"server\",\n \"cloud\",\n \"globe\",\n \"monitor\",\n \"smartphone\",\n \"key\",\n \"lock\",\n \"shield\",\n \"brain\",\n \"sparkles\",\n \"bot\",\n \"workflow\",\n \"file\",\n \"folder\",\n \"book\",\n \"table\",\n \"image\",\n \"video\",\n \"mic\",\n \"speech\",\n \"paperclip\",\n \"message\",\n \"mail\",\n \"bell\",\n \"calendar\",\n \"clock\",\n \"user\",\n \"users\",\n \"settings\",\n \"wrench\",\n \"plug\",\n \"link\",\n \"palette\",\n \"search\",\n \"zap\",\n \"check\",\n \"question\",\n] as const;\n\nexport type OptionIcon = (typeof OPTION_ICONS)[number];\n\nexport const isOptionIcon = (value: string): value is OptionIcon =>\n (OPTION_ICONS as readonly string[]).includes(value);\n\nexport const parseChoiceAnswer = (answer: string) => {\n const parts = answer.split(\":\");\n if (parts.length > 2) return { option: answer };\n const [option = \"\", variant] = parts;\n return { option, ...(variant !== undefined && { variant }) };\n};\n\n/** The entries of a multiple choice answer, or `undefined` when the text is not a JSON array of strings. */\nexport const parseMultipleAnswer = (answer: string): string[] | undefined => {\n let value: unknown;\n try {\n value = JSON.parse(answer);\n } catch {\n return undefined;\n }\n return Array.isArray(value) &&\n value.every((entry) => typeof entry === \"string\")\n ? value\n : undefined;\n};\n\ntype ChoiceAnswerKind = \"option\" | \"custom\" | \"invalid\";\n\nconst classifyChoiceEntry = (\n input: Checkout.Input,\n answer: string,\n): ChoiceAnswerKind => {\n const { option, variant } = parseChoiceAnswer(answer);\n const match = input.options?.find((candidate) => candidate.id === option);\n if (!match) return answer.trim() === \"\" ? \"invalid\" : \"custom\";\n if (!match.variants || match.variants.length === 0) {\n return variant === undefined ? \"option\" : \"invalid\";\n }\n return match.variants.some((candidate) => candidate.id === variant)\n ? \"option\"\n : \"invalid\";\n};\n\n/**\n * \"option\" when `answer` names one of the input's options (with a variant\n * when the option has them), \"custom\" for the user's own text, \"invalid\"\n * for an option named without its variant or with an unknown one. A\n * multiple choice is classified entry by entry: \"invalid\" when any entry is\n * or the array is empty, \"custom\" when any entry is the user's own text.\n */\nexport const classifyChoiceAnswer = (\n input: Checkout.Input,\n answer: string,\n): ChoiceAnswerKind => {\n if (!input.multiple) return classifyChoiceEntry(input, answer);\n const entries = parseMultipleAnswer(answer);\n if (!entries || entries.length === 0) return \"invalid\";\n const kinds = entries.map((entry) => classifyChoiceEntry(input, entry));\n if (kinds.includes(\"invalid\")) return \"invalid\";\n return kinds.includes(\"custom\") ? \"custom\" : \"option\";\n};\n\nconst isEntryPointText = (value: unknown, max: number): value is string =>\n typeof value === \"string\" && value.trim() !== \"\" && value.length <= max;\n\nexport const parseEntryPointOptions = (\n value: unknown,\n): Checkout.EntryPointOption[] | undefined => {\n if (!Array.isArray(value) || value.length < 1 || value.length > 3)\n return undefined;\n const options: Checkout.EntryPointOption[] = [];\n for (const candidate of value) {\n if (typeof candidate !== \"object\" || candidate === null) return undefined;\n const { id, label, description, entryPoint, variants } =\n candidate as Record<string, unknown>;\n if (\n typeof id !== \"string\" ||\n !/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$/.test(id) ||\n options.some((option) => option.id === id) ||\n !isEntryPointText(label, 160) ||\n !isEntryPointText(description, 1000) ||\n variants !== undefined ||\n typeof entryPoint !== \"object\" ||\n entryPoint === null\n )\n return undefined;\n const { formFactor, placement, trigger, recommended } =\n entryPoint as Record<string, unknown>;\n if (\n (formFactor !== \"modal\" &&\n formFactor !== \"sidebar\" &&\n formFactor !== \"full-page\") ||\n !isEntryPointText(placement, 400) ||\n !isEntryPointText(trigger, 400) ||\n (recommended !== undefined && typeof recommended !== \"boolean\")\n )\n return undefined;\n options.push({\n id,\n label,\n description,\n entryPoint: {\n formFactor,\n placement,\n trigger,\n ...(recommended !== undefined && { recommended }),\n },\n });\n }\n return options.filter((option) => option.entryPoint.recommended).length <= 1\n ? options\n : undefined;\n};\n\nexport const isValidEntryPointInput = (input: Checkout.InputSeed) => {\n const options = parseEntryPointOptions(input.options);\n return (\n input.kind === \"entry-point\" &&\n isEntryPointText(input.prompt, 1000) &&\n options !== undefined &&\n input.multiple === undefined &&\n input.help === undefined &&\n (input.default === undefined ||\n options.some((option) => option.id === input.default))\n );\n};\n\nexport const isValidEntryPointAnswer = (\n input: Checkout.Input,\n answer: string,\n) => input.options?.some((option) => option.id === answer) ?? false;\n\nconst REASONING_EFFORTS = new Set([\"low\", \"medium\", \"high\"]);\n\nconst isReasoningEffort = (\n value: unknown,\n): value is NonNullable<Checkout.ModelAnswer[\"reasoningEffort\"]> =>\n typeof value === \"string\" && REASONING_EFFORTS.has(value);\n\n/** The model answer an input holds, or `undefined` when the text is not one. */\nexport const parseModelAnswer = (\n answer: string,\n): Checkout.ModelAnswer | undefined => {\n let value: unknown;\n try {\n value = JSON.parse(answer);\n } catch {\n return undefined;\n }\n if (typeof value !== \"object\" || value === null) return undefined;\n const { provider, model, reasoningEffort } = value as Record<string, unknown>;\n if (\n typeof provider !== \"string\" ||\n typeof model !== \"string\" ||\n provider === \"\" ||\n model === \"\"\n ) {\n return undefined;\n }\n if (reasoningEffort === undefined) return { provider, model };\n if (!isReasoningEffort(reasoningEffort)) return undefined;\n return { provider, model, reasoningEffort };\n};\n\n/** Whether `answer` is a model answer naming one of the input's providers. */\nexport const isValidModelAnswer = (input: Checkout.Input, answer: string) => {\n const parsed = parseModelAnswer(answer);\n return (\n parsed !== undefined &&\n (input.options?.some((option) => option.id === parsed.provider) ?? false)\n );\n};\n\nexport const stepProgress = (state: Checkout.State) => ({\n total: state.steps.length,\n done: state.steps.filter(\n (step) => step.status === \"done\" || step.status === \"skipped\",\n ).length,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"protocol.js","names":[],"sources":["../src/protocol.ts"],"sourcesContent":["export namespace Checkout {\n export type StepStatus =\n | \"pending\"\n | \"active\"\n | \"done\"\n | \"skipped\"\n | \"blocked\";\n\n /** A unit of install work the agent declared; the catalog seeds none. */\n export type Step = {\n id: string;\n title: string;\n detail?: string;\n status: StepStatus;\n note?: string;\n /** The product this step belongs to, when the agent said. */\n product?: string;\n createdAt: number;\n };\n\n export type Product = {\n slug: string;\n name: string;\n /** The install reference the agent fetches while planning. */\n guide?: string;\n };\n\n export type InputStatus = \"open\" | \"answered\" | \"dismissed\";\n\n /**\n * product: the agent proposes adding a product to this checkout, such as one\n * another product depends on. The browser owns the catalog, so it answers\n * with `checkout/add-product`; dismissing the input declines.\n */\n export type InputKind =\n | \"text\"\n | \"choice\"\n | \"model\"\n | \"product\"\n | \"entry-point\";\n\n export type EntryPoint = {\n formFactor: \"modal\" | \"sidebar\" | \"full-page\";\n placement: string;\n trigger: string;\n recommended?: boolean;\n };\n\n export type EntryPointOption = {\n id: string;\n label: string;\n description: string;\n entryPoint: EntryPoint;\n };\n\n export type ChoiceVariant = { id: string; label: string };\n\n export type ChoiceOption = {\n id: string;\n label: string;\n description?: string;\n /** A name from OPTION_ICONS, or the key of a brand mark on a preset option; unknown keys render without one. */\n icon?: string;\n /** A second pick under this option, such as the language of a framework. */\n variants?: ChoiceVariant[];\n entryPoint?: EntryPoint;\n };\n\n /** A short nudge for users who need help choosing, with a longer guide to link to. */\n export type InputHelp = { summary: string; href?: string };\n\n /**\n * The answer to a model input, stored as JSON text. The API key itself is\n * never part of it: the browser deposits it with the checkout and the\n * agent's `env` command writes it straight to a file.\n */\n export type ModelAnswer = {\n provider: string;\n model: string;\n reasoningEffort?: \"low\" | \"medium\" | \"high\";\n };\n\n /**\n * A choice answer is an option id, `<option>:<variant>` when the option has\n * variants, or the user's own text when none of the options fit; a multiple\n * choice answers a JSON array of those. A model answer is a JSON-encoded\n * ModelAnswer whose provider is one of the options.\n */\n export type Input = {\n phase: Status;\n id: string;\n kind: InputKind;\n /** The standard input this was built from, when it was. */\n preset?: string;\n prompt: string;\n placeholder?: string;\n options?: ChoiceOption[];\n /** The user may pick any number of options; the answer is a JSON array. */\n multiple?: true;\n /** The slug a product input proposes. */\n product?: string;\n default?: string;\n help?: InputHelp;\n redeemKeyHash?: string;\n optional: boolean;\n status: InputStatus;\n answer?: string;\n /** A remark the user attached to the answer. */\n note?: string;\n stepId?: string;\n createdAt: number;\n answeredAt?: number;\n };\n\n export type LogEntry = {\n phase: Status;\n id: string;\n role: \"agent\" | \"user\";\n acknowledgedAt?: number;\n at: number;\n text: string;\n /** The step that was active when the line was posted; none while planning. */\n stepId?: string;\n };\n\n export type PlanStatus = \"proposed\" | \"approved\" | \"changes-requested\";\n\n /** One revision of the agent's plan. Markdown the browser renders. */\n export type Plan = {\n revision: number;\n markdown: string;\n status: PlanStatus;\n submittedAt: number;\n decidedAt?: number;\n /** What the user asked to change, when they did. */\n feedback?: string;\n };\n\n /**\n * waiting: no agent has joined. planning: the agent investigates and\n * proposes a plan. installing: the plan is approved and steps run.\n */\n export type Status =\n | \"waiting\"\n | \"planning\"\n | \"installing\"\n | \"done\"\n | \"cancelled\";\n\n /**\n * The agent's proposal to close the checkout. Only the user closes it, and\n * they may keep messaging the agent instead; a later `done` renews it.\n * `preview` is the loopback URL of a dev server the agent left running for\n * the user to try before they close.\n */\n export type Completion = { proposedAt: number; preview?: string };\n\n export type State = {\n version: 2;\n /** The id the browser gave the current checkout; a create with another id replaces it on the same link. */\n id: string | null;\n status: Status;\n completion?: Completion;\n createdAt: number | null;\n products: Product[];\n instructions: string;\n agent: {\n lastSeenAt: number | null;\n /** False once the agent's stream said goodbye; heartbeats set it again. */\n connected: boolean;\n cwd: string | null;\n /** The coding agent that ran the command, as the CLI detected it from its environment. */\n kind: string | null;\n /** When the command was first run against this checkout, before the agent joined the stream. */\n introducedAt: number | null;\n };\n /** Every revision in order; the last one is current. */\n plans: Plan[];\n steps: Step[];\n inputs: Input[];\n log: LogEntry[];\n };\n\n export type ProductSeed = { slug: string; name: string; guide?: string };\n\n export type InputSeed = {\n kind?: InputKind;\n preset?: string;\n prompt: string;\n placeholder?: string;\n options?: ChoiceOption[];\n multiple?: true;\n product?: string;\n default?: string;\n help?: InputHelp;\n redeemKeyHash?: string;\n optional?: boolean;\n };\n\n export type PlanDecision = {\n /** The setup the browser reviewed; omitted by legacy clients. */\n id?: string;\n /** The plan revision the browser reviewed; omitted by legacy clients. */\n revision?: number;\n } & ({ decision: \"approve\" } | { decision: \"revise\"; feedback: string });\n\n export type Commands = {\n \"checkout/create\": (params: {\n id: string;\n products: ProductSeed[];\n instructions?: string;\n }) => void;\n \"checkout/begin-plan\": () => void;\n \"checkout/answer\": (params: {\n inputId: string;\n answer: string;\n note?: string;\n }) => void;\n \"checkout/add-product\": (params: {\n inputId: string;\n product: ProductSeed;\n }) => void;\n \"checkout/message\": (params: { text: string }) => void;\n \"agent/ack\": (params: { messageId: string }) => void;\n \"checkout/dismiss\": (params: { inputId: string }) => void;\n \"checkout/plan\": (params: PlanDecision) => void;\n /** A cancel that names another checkout than the current one is a no-op. */\n \"checkout/cancel\": (params?: { id?: string }) => void;\n \"checkout/finish\": () => void;\n \"agent/intro\": (params: { kind?: string }) => void;\n \"agent/hello\": (params: { cwd?: string; kind?: string }) => void;\n \"agent/heartbeat\": () => void;\n \"agent/bye\": () => void;\n \"agent/plan\": (params: { markdown: string }) => { revision: number };\n \"agent/add-step\": (params: {\n title: string;\n detail?: string;\n product?: string;\n /** Start the step in the same call. */\n active?: boolean;\n }) => { stepId: string };\n \"agent/step\": (params: {\n stepId: string;\n status: StepStatus;\n note?: string;\n }) => void;\n \"agent/ask\": (params: InputSeed & { stepId?: string }) => {\n inputId: string;\n };\n \"agent/log\": (params: { text: string }) => void;\n \"agent/done\": (params?: { summary?: string; preview?: string }) => void;\n };\n\n export type RejectionReason =\n | \"already-created\"\n | \"not-created\"\n | \"closed\"\n | \"planning-not-started\"\n | \"plan-required\"\n | \"no-plan\"\n | \"plan-decided\"\n | \"stale-plan\"\n | \"finish-not-proposed\"\n | \"feedback-required\"\n | \"empty-plan\"\n | \"unknown-step\"\n | \"unknown-product\"\n | \"unknown-input\"\n | \"input-closed\"\n | \"invalid-input\"\n | \"invalid-answer\"\n | \"invalid-preview\"\n | \"empty-message\"\n | \"unknown-message\";\n}\n\nexport const AGENT_PRESENCE_MS = 15_000;\nexport const AGENT_HEARTBEAT_MS = 5_000;\n\nexport const initialCheckoutState = (): Checkout.State => ({\n version: 2,\n id: null,\n status: \"waiting\",\n createdAt: null,\n products: [],\n instructions: \"\",\n agent: {\n lastSeenAt: null,\n connected: false,\n cwd: null,\n kind: null,\n introducedAt: null,\n },\n plans: [],\n steps: [],\n inputs: [],\n log: [],\n});\n\nexport const isAgentPresent = (state: Checkout.State, now = Date.now()) =>\n state.agent.connected &&\n state.agent.lastSeenAt !== null &&\n now - state.agent.lastSeenAt < AGENT_PRESENCE_MS;\n\nexport const isClosed = (state: Checkout.State) =>\n state.status === \"done\" || state.status === \"cancelled\";\n\n/** True while the agent's proposal to close waits for the user. */\nexport const finishProposed = (state: Checkout.State) =>\n !isClosed(state) && state.completion !== undefined;\n\n/** True while a message the user sent after the agent proposed to close still waits for the agent. */\nexport const followedUpSinceProposal = (state: Checkout.State) => {\n const proposedAt = state.completion?.proposedAt;\n return (\n proposedAt !== undefined &&\n state.log.some(\n (entry) =>\n entry.role === \"user\" &&\n entry.at > proposedAt &&\n entry.acknowledgedAt === undefined,\n )\n );\n};\n\nconst LOOPBACK_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"[::1]\"]);\n\n/**\n * The URL a preview names, or `undefined` unless it is an http(s) URL on this\n * machine's loopback interface. The browser opens it, so nothing else passes.\n */\nexport const parsePreviewUrl = (value: string | undefined) => {\n if (!value) return undefined;\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n return undefined;\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") return undefined;\n if (url.username !== \"\" || url.password !== \"\") return undefined;\n const loopback =\n LOOPBACK_HOSTS.has(url.hostname) || url.hostname.endsWith(\".localhost\");\n return loopback ? url : undefined;\n};\n\nexport const openInputs = (state: Checkout.State) =>\n state.inputs.filter((input) => input.status === \"open\");\n\n/** The current plan revision, or `undefined` before the agent proposed one. */\nexport const currentPlan = (state: Checkout.State): Checkout.Plan | undefined =>\n state.plans.at(-1);\n\n/** True while a proposed plan waits for the user's decision. */\nexport const planNeedsReview = (state: Checkout.State) =>\n !isClosed(state) && currentPlan(state)?.status === \"proposed\";\n\n/** The icons an agent can put on its own options, by name. */\nexport const OPTION_ICONS = [\n \"code\",\n \"terminal\",\n \"braces\",\n \"git-branch\",\n \"package\",\n \"database\",\n \"server\",\n \"cloud\",\n \"globe\",\n \"monitor\",\n \"smartphone\",\n \"key\",\n \"lock\",\n \"shield\",\n \"brain\",\n \"sparkles\",\n \"bot\",\n \"workflow\",\n \"file\",\n \"folder\",\n \"book\",\n \"table\",\n \"image\",\n \"video\",\n \"mic\",\n \"speech\",\n \"paperclip\",\n \"message\",\n \"mail\",\n \"bell\",\n \"calendar\",\n \"clock\",\n \"user\",\n \"users\",\n \"settings\",\n \"wrench\",\n \"plug\",\n \"link\",\n \"palette\",\n \"search\",\n \"zap\",\n \"check\",\n \"question\",\n] as const;\n\nexport type OptionIcon = (typeof OPTION_ICONS)[number];\n\nexport const isOptionIcon = (value: string): value is OptionIcon =>\n (OPTION_ICONS as readonly string[]).includes(value);\n\nexport const parseChoiceAnswer = (answer: string) => {\n const parts = answer.split(\":\");\n if (parts.length > 2) return { option: answer };\n const [option = \"\", variant] = parts;\n return { option, ...(variant !== undefined && { variant }) };\n};\n\n/** The entries of a multiple choice answer, or `undefined` when the text is not a JSON array of strings. */\nexport const parseMultipleAnswer = (answer: string): string[] | undefined => {\n let value: unknown;\n try {\n value = JSON.parse(answer);\n } catch {\n return undefined;\n }\n return Array.isArray(value) &&\n value.every((entry) => typeof entry === \"string\")\n ? value\n : undefined;\n};\n\ntype ChoiceAnswerKind = \"option\" | \"custom\" | \"invalid\";\n\nconst classifyChoiceEntry = (\n input: Checkout.Input,\n answer: string,\n): ChoiceAnswerKind => {\n const { option, variant } = parseChoiceAnswer(answer);\n const match = input.options?.find((candidate) => candidate.id === option);\n if (!match) return answer.trim() === \"\" ? \"invalid\" : \"custom\";\n if (!match.variants || match.variants.length === 0) {\n return variant === undefined ? \"option\" : \"invalid\";\n }\n return match.variants.some((candidate) => candidate.id === variant)\n ? \"option\"\n : \"invalid\";\n};\n\n/**\n * \"option\" when `answer` names one of the input's options (with a variant\n * when the option has them), \"custom\" for the user's own text, \"invalid\"\n * for an option named without its variant or with an unknown one. A\n * multiple choice is classified entry by entry: \"invalid\" when any entry is\n * or the array is empty, \"custom\" when any entry is the user's own text.\n */\nexport const classifyChoiceAnswer = (\n input: Checkout.Input,\n answer: string,\n): ChoiceAnswerKind => {\n if (!input.multiple) return classifyChoiceEntry(input, answer);\n const entries = parseMultipleAnswer(answer);\n if (!entries || entries.length === 0) return \"invalid\";\n const kinds = entries.map((entry) => classifyChoiceEntry(input, entry));\n if (kinds.includes(\"invalid\")) return \"invalid\";\n return kinds.includes(\"custom\") ? \"custom\" : \"option\";\n};\n\nconst isEntryPointText = (value: unknown, max: number): value is string =>\n typeof value === \"string\" && value.trim() !== \"\" && value.length <= max;\n\nexport const parseEntryPointOptions = (\n value: unknown,\n): Checkout.EntryPointOption[] | undefined => {\n if (!Array.isArray(value) || value.length < 1 || value.length > 3)\n return undefined;\n const options: Checkout.EntryPointOption[] = [];\n for (const candidate of value) {\n if (typeof candidate !== \"object\" || candidate === null) return undefined;\n const { id, label, description, entryPoint, variants } =\n candidate as Record<string, unknown>;\n if (\n typeof id !== \"string\" ||\n !/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$/.test(id) ||\n options.some((option) => option.id === id) ||\n !isEntryPointText(label, 160) ||\n !isEntryPointText(description, 1000) ||\n variants !== undefined ||\n typeof entryPoint !== \"object\" ||\n entryPoint === null\n )\n return undefined;\n const { formFactor, placement, trigger, recommended } =\n entryPoint as Record<string, unknown>;\n if (\n (formFactor !== \"modal\" &&\n formFactor !== \"sidebar\" &&\n formFactor !== \"full-page\") ||\n !isEntryPointText(placement, 400) ||\n !isEntryPointText(trigger, 400) ||\n (recommended !== undefined && typeof recommended !== \"boolean\")\n )\n return undefined;\n options.push({\n id,\n label,\n description,\n entryPoint: {\n formFactor,\n placement,\n trigger,\n ...(recommended !== undefined && { recommended }),\n },\n });\n }\n return options.filter((option) => option.entryPoint.recommended).length <= 1\n ? options\n : undefined;\n};\n\nexport const isValidEntryPointInput = (input: Checkout.InputSeed) => {\n const options = parseEntryPointOptions(input.options);\n return (\n input.kind === \"entry-point\" &&\n isEntryPointText(input.prompt, 1000) &&\n options !== undefined &&\n input.multiple === undefined &&\n input.help === undefined &&\n (input.default === undefined ||\n options.some((option) => option.id === input.default))\n );\n};\n\nexport const isValidEntryPointAnswer = (\n input: Checkout.Input,\n answer: string,\n) => input.options?.some((option) => option.id === answer) ?? false;\n\nconst REASONING_EFFORTS = new Set([\"low\", \"medium\", \"high\"]);\n\nconst isReasoningEffort = (\n value: unknown,\n): value is NonNullable<Checkout.ModelAnswer[\"reasoningEffort\"]> =>\n typeof value === \"string\" && REASONING_EFFORTS.has(value);\n\n/** The model answer an input holds, or `undefined` when the text is not one. */\nexport const parseModelAnswer = (\n answer: string,\n): Checkout.ModelAnswer | undefined => {\n let value: unknown;\n try {\n value = JSON.parse(answer);\n } catch {\n return undefined;\n }\n if (typeof value !== \"object\" || value === null) return undefined;\n const { provider, model, reasoningEffort } = value as Record<string, unknown>;\n if (\n typeof provider !== \"string\" ||\n typeof model !== \"string\" ||\n provider === \"\" ||\n model === \"\"\n ) {\n return undefined;\n }\n if (reasoningEffort === undefined) return { provider, model };\n if (!isReasoningEffort(reasoningEffort)) return undefined;\n return { provider, model, reasoningEffort };\n};\n\n/** Whether `answer` is a model answer naming one of the input's providers. */\nexport const isValidModelAnswer = (input: Checkout.Input, answer: string) => {\n const parsed = parseModelAnswer(answer);\n return (\n parsed !== undefined &&\n (input.options?.some((option) => option.id === parsed.provider) ?? false)\n );\n};\n\nexport const stepProgress = (state: Checkout.State) => ({\n total: state.steps.length,\n done: state.steps.filter(\n (step) => step.status === \"done\" || step.status === \"skipped\",\n ).length,\n});\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "setup-agent",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "A live setup shared between a browser and the coding agent installing the products in it, on Statewire",
5
5
  "license": "MIT",
6
6
  "homepage": "https://www.assistant-ui.com/",
@@ -44,10 +44,10 @@
44
44
  ],
45
45
  "dependencies": {
46
46
  "@assistant-ui/tap": "^0.9.24",
47
- "statewire": "^0.20.0"
47
+ "statewire": "^0.22.1"
48
48
  },
49
49
  "devDependencies": {
50
- "@assistant-ui/x-buildutils": "0.0.31",
50
+ "@assistant-ui/x-buildutils": "0.0.32",
51
51
  "@types/node": "^26.6.5",
52
52
  "@types/react": "^19.3.0",
53
53
  "react": "^19.3.1",