@smthrs/std 1.0.0-rc.4 → 1.0.0-rc.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +3 -3
  2. package/dist/cjs/ExaWebSearch.js +1 -1
  3. package/dist/cjs/ExaWebSearch.js.map +1 -1
  4. package/dist/cjs/Fetch.d.ts +1 -1
  5. package/dist/cjs/Fetch.d.ts.map +1 -1
  6. package/dist/cjs/Fetch.js +1 -1
  7. package/dist/cjs/Fetch.js.map +2 -2
  8. package/dist/cjs/HttpPost.d.ts +1 -1
  9. package/dist/cjs/HttpPost.d.ts.map +1 -1
  10. package/dist/cjs/HttpPost.js +1 -1
  11. package/dist/cjs/HttpPost.js.map +2 -2
  12. package/dist/cjs/Lsp.d.ts +1 -1
  13. package/dist/cjs/Manifest.d.ts +8 -8
  14. package/dist/cjs/NodeLanguageServer.js +1 -1
  15. package/dist/cjs/NodeLanguageServer.js.map +1 -1
  16. package/dist/cjs/WebFetch.d.ts.map +1 -1
  17. package/dist/cjs/WebFetch.js +1 -1
  18. package/dist/cjs/WebFetch.js.map +2 -2
  19. package/dist/cjs/internal/Exec.d.ts.map +1 -1
  20. package/dist/cjs/internal/Exec.js +1 -1
  21. package/dist/cjs/internal/Exec.js.map +2 -2
  22. package/dist/cjs/internal/Http.d.ts +1 -1
  23. package/dist/cjs/internal/Http.d.ts.map +1 -1
  24. package/dist/cjs/internal/Http.js +1 -1
  25. package/dist/cjs/internal/Http.js.map +2 -2
  26. package/dist/cjs/internal/HttpNetwork.d.ts +2 -2
  27. package/dist/cjs/internal/HttpNetwork.d.ts.map +1 -1
  28. package/dist/cjs/internal/HttpNetwork.js +3 -3
  29. package/dist/cjs/internal/HttpNetwork.js.map +1 -1
  30. package/dist/esm/ExaWebSearch.js +1 -1
  31. package/dist/esm/ExaWebSearch.js.map +1 -1
  32. package/dist/esm/Fetch.d.ts +1 -1
  33. package/dist/esm/Fetch.d.ts.map +1 -1
  34. package/dist/esm/Fetch.js +1 -1
  35. package/dist/esm/Fetch.js.map +1 -1
  36. package/dist/esm/HttpPost.d.ts +1 -1
  37. package/dist/esm/HttpPost.d.ts.map +1 -1
  38. package/dist/esm/HttpPost.js +1 -1
  39. package/dist/esm/HttpPost.js.map +1 -1
  40. package/dist/esm/Lsp.d.ts +1 -1
  41. package/dist/esm/Manifest.d.ts +8 -8
  42. package/dist/esm/NodeLanguageServer.js +1 -1
  43. package/dist/esm/NodeLanguageServer.js.map +1 -1
  44. package/dist/esm/WebFetch.d.ts.map +1 -1
  45. package/dist/esm/WebFetch.js +1 -1
  46. package/dist/esm/WebFetch.js.map +1 -1
  47. package/dist/esm/internal/Exec.d.ts.map +1 -1
  48. package/dist/esm/internal/Exec.js +1 -1
  49. package/dist/esm/internal/Exec.js.map +1 -1
  50. package/dist/esm/internal/Http.d.ts +1 -1
  51. package/dist/esm/internal/Http.d.ts.map +1 -1
  52. package/dist/esm/internal/Http.js +1 -1
  53. package/dist/esm/internal/Http.js.map +1 -1
  54. package/dist/esm/internal/HttpNetwork.d.ts +2 -2
  55. package/dist/esm/internal/HttpNetwork.d.ts.map +1 -1
  56. package/dist/esm/internal/HttpNetwork.js +3 -3
  57. package/dist/esm/internal/HttpNetwork.js.map +1 -1
  58. package/docs/guides/run-a-shell-command.md +8 -0
  59. package/docs/installation.md +1 -1
  60. package/docs/troubleshooting.md +5 -0
  61. package/package.json +10 -10
  62. package/src/ExaWebSearch.ts +1 -1
  63. package/src/Fetch.ts +1 -1
  64. package/src/HttpPost.ts +1 -1
  65. package/src/NodeLanguageServer.ts +1 -1
  66. package/src/WebFetch.ts +1 -1
  67. package/src/internal/Exec.ts +1 -1
  68. package/src/internal/Http.ts +1 -1
  69. package/src/internal/HttpNetwork.ts +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"Exec.js","sourceRoot":"","sources":["../../../src/internal/Exec.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Buffered shell execution over the permission-aware process spawner.\n *\n * `@smthrs/kernel` used to expose a `Shell` service whose `exec` returned a\n * buffered `{ stdout, stderr, exitCode }`. The kernel replaced it with\n * `ChildProcessSpawner`, Effect's own process boundary, which streams and has\n * no buffered form. This module is the buffered form the shell flows still\n * want, expressed in terms of the spawner so the `proc:spawn` capability check\n * and the command-line resource stay exactly where the kernel put them.\n *\n * Commands run through the platform shell (`shell: true`), matching the old\n * service: the flows take a command *line*, not an argv.\n *\n * @since 1.0.0\n */\n\nimport * as ChildProcessEnvironment from \"@smthrs/kernel/ChildProcessEnvironment\"\nimport * as ChildProcessSpawner from \"@smthrs/kernel/ChildProcessSpawner\"\nimport * as Effect from \"effect/Effect\"\nimport * as Schema from \"effect/Schema\"\nimport * as Stream from \"effect/Stream\"\nimport * as ChildProcess from \"effect/unstable/process/ChildProcess\"\nimport * as StdError from \"../StdError.ts\"\n\n/**\n * Failure codes a buffered execution can report, matching the codes the\n * removed kernel `Shell` used so handler-level mapping is unchanged.\n *\n * @category models\n * @since 1.0.0\n */\nexport const ExecErrorCode = Schema.Literals([\"timeout\", \"spawn_error\", \"capture_overflow\"])\n\n/**\n * Failure codes a buffered execution can report.\n *\n * @category models\n * @since 1.0.0\n */\nexport type ExecErrorCode = typeof ExecErrorCode.Type\n\n/**\n * A command that never produced an exit code.\n *\n * A non-zero exit is a successful {@link ExecResult}, not a failure; this\n * error is reserved for a command that could not start or was cut off by its\n * timeout, or whose captured output exceeded a refusing capture bound.\n *\n * @category errors\n * @since 1.0.0\n */\nexport class ExecError extends Schema.TaggedError<ExecError>()(\"@smthrs/std/ExecError\", {\n code: ExecErrorCode,\n message: Schema.String,\n /** The limit a `timeout` ran past, in milliseconds. */\n limitMillis: Schema.optional(Schema.Number)\n}) {}\n\n/**\n * The buffered result of one command.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface ExecResult {\n readonly stdout: string\n readonly stderr: string\n readonly exitCode: number\n /** UTF-8 bytes dropped from the head of stdout to stay inside the capture bound. */\n readonly stdoutDroppedBytes: number\n /** UTF-8 bytes dropped from the head of stderr to stay inside the capture bound. */\n readonly stderrDroppedBytes: number\n}\n\n/**\n * Options accepted by {@link exec}.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface ExecOptions {\n readonly cwd?: string | undefined\n readonly env?: Readonly<Record<string, string>> | undefined\n readonly timeoutMs?: number | undefined\n /**\n * The program's arguments. Present means an argv, absent means a command\n * line for the platform shell. An argv is how a payload reaches a program\n * without being quoted into a string: nothing between here and `execve`\n * re-parses it.\n */\n readonly args?: ReadonlyArray<string> | undefined\n /**\n * Text written to the program's standard input, as data. A script delivered\n * this way is never quoted, escaped, or heredoc-terminated, which is the\n * whole point: quoting corruption cost the measured SWE-bench program twelve\n * probe failures and one instance's most expensive frame.\n */\n readonly stdin?: string | undefined\n /**\n * Bytes retained per captured stream. A stream that prints more keeps its\n * tail and reports what it dropped, so a command printing gigabytes costs a\n * bounded amount of memory rather than the whole of what it printed.\n *\n * Absent means unbounded, which is what a caller wants when it needs every\n * byte a tool produced (`rg --files`, `git worktree list`).\n */\n readonly maxCaptureBytes?: number | undefined\n /** Defaults to `tail`; `refuse` fails if either stream exceeds the bound. */\n readonly overflow?: \"tail\" | \"refuse\" | undefined\n}\n\n/** One captured stream: the text kept, and the bytes dropped to keep it bounded. */\ninterface Capture {\n readonly text: string\n readonly droppedBytes: number\n}\n\ninterface Tail {\n chunks: Array<Uint8Array>\n bytes: number\n dropped: number\n}\n\nconst decoder = new TextDecoder(\"utf-8\")\n\n/**\n * Joins the retained chunks and decodes them, skipping the partial code point a\n * dropped head can leave behind.\n *\n * A UTF-8 continuation byte is `10xxxxxx`, and a code point is at most four\n * bytes, so at most three leading continuation bytes can precede the first\n * whole character. Skipping them is counted as dropped rather than decoded to a\n * replacement character the process never printed.\n */\nconst decodeTail = (state: Tail): Capture => {\n const bytes = new Uint8Array(state.bytes)\n let offset = 0\n for (const chunk of state.chunks) {\n bytes.set(chunk, offset)\n offset += chunk.byteLength\n }\n if (state.dropped === 0) return { text: decoder.decode(bytes), droppedBytes: 0 }\n let start = 0\n while (start < bytes.byteLength && start < 3 && (bytes[start]! & 0b1100_0000) === 0b1000_0000) start++\n return { text: decoder.decode(bytes.subarray(start)), droppedBytes: state.dropped + start }\n}\n\nconst boundedTail = <E>(\n stream: Stream.Stream<Uint8Array, E>,\n maxBytes: number,\n overflow: \"tail\" | \"refuse\" | undefined\n): Effect.Effect<Capture, E> =>\n Stream.runFold(\n stream,\n (): Tail => ({ chunks: [], bytes: 0, dropped: 0 }),\n (state, chunk) => {\n if (chunk.byteLength === 0) return state\n state.chunks.push(chunk)\n state.bytes += chunk.byteLength\n while (state.bytes > maxBytes && state.chunks.length > 0) {\n const excess = state.bytes - maxBytes\n const first = state.chunks[0]!\n if (first.byteLength <= excess) {\n state.chunks.shift()\n state.bytes -= first.byteLength\n state.dropped += first.byteLength\n } else {\n state.chunks[0] = first.subarray(excess)\n state.bytes -= excess\n state.dropped += excess\n }\n }\n return state\n }\n ).pipe(Effect.map((state) =>\n overflow === \"refuse\" && state.dropped > 0\n ? { text: \"\", droppedBytes: state.dropped }\n : decodeTail(state)\n ))\n\nconst capture = <E>(\n stream: Stream.Stream<Uint8Array, E>,\n maxBytes: number | undefined,\n overflow: \"tail\" | \"refuse\" | undefined\n): Effect.Effect<Capture, E> =>\n maxBytes === undefined\n ? Effect.map(Stream.mkString(Stream.decodeText(stream)), (text) => ({ text, droppedBytes: 0 }))\n : boundedTail(stream, maxBytes, overflow)\n\nconst unbounded = (\n command: string,\n options: ExecOptions\n): Effect.Effect<ExecResult, ExecError, ChildProcessSpawner.ChildProcessSpawner> =>\n Effect.gen(function*() {\n const spawner = yield* ChildProcessSpawner.ChildProcessSpawner\n const settings: ChildProcess.CommandOptions = {\n ...(options.args === undefined ? { shell: true } : {}),\n ...(options.cwd === undefined ? {} : { cwd: options.cwd }),\n env: ChildProcessEnvironment.make(process.env, options.env),\n extendEnv: false,\n ...(options.stdin === undefined\n ? {}\n : { stdin: Stream.make(new TextEncoder().encode(options.stdin)) })\n }\n const handle = yield* spawner.spawn(\n options.args === undefined\n ? ChildProcess.make(command, settings)\n : ChildProcess.make(command, [...options.args], settings)\n )\n // stdout, stderr, and the exit code have to be consumed concurrently: a\n // command that fills a pipe blocks until the pipe is drained, so waiting\n // for exit first would deadlock on any output larger than the buffer.\n const [stdout, stderr, exitCode] = yield* Effect.all(\n [\n capture(handle.stdout, options.maxCaptureBytes, options.overflow),\n capture(handle.stderr, options.maxCaptureBytes, options.overflow),\n handle.exitCode\n ],\n { concurrency: \"unbounded\" }\n )\n if (options.overflow === \"refuse\") {\n const overflowed = [\n stdout.droppedBytes > 0 ? \"stdout\" : undefined,\n stderr.droppedBytes > 0 ? \"stderr\" : undefined\n ]\n .filter((stream): stream is string => stream !== undefined)\n if (overflowed.length > 0) {\n return yield* Effect.fail(\n new ExecError({\n code: \"capture_overflow\",\n message: `${command} ${\n overflowed.join(\" and \")\n } exceeded the ${options.maxCaptureBytes}-byte capture cap; refusing partial output`\n })\n )\n }\n }\n return {\n stdout: stdout.text,\n stderr: stderr.text,\n exitCode,\n stdoutDroppedBytes: stdout.droppedBytes,\n stderrDroppedBytes: stderr.droppedBytes\n }\n }).pipe(\n Effect.scoped,\n Effect.mapError((error) =>\n error instanceof ExecError ? error : new ExecError({\n code: \"spawn_error\",\n message: `exec: ${command}: ${error.message}`\n })\n )\n )\n\n/**\n * Runs a command line through the platform shell and buffers its output.\n *\n * Cancellation is scope closure: the spawn is scoped, so an interrupted fiber\n * — including the one a `timeoutMs` interrupts — terminates the process rather\n * than leaking it.\n *\n * @category execution\n * @since 1.0.0\n */\nexport const exec = (\n command: string,\n options: ExecOptions = {}\n): Effect.Effect<ExecResult, ExecError, ChildProcessSpawner.ChildProcessSpawner> =>\n options.timeoutMs === undefined\n ? unbounded(command, options)\n : Effect.timeoutOrElse(unbounded(command, options), {\n duration: options.timeoutMs,\n orElse: () =>\n Effect.fail(\n new ExecError({\n code: \"timeout\",\n message: `exec: \\`${command}\\` exceeded ${options.timeoutMs}ms`,\n limitMillis: options.timeoutMs\n })\n )\n })\n\n/**\n * The model-facing failure code a command that never produced an exit code\n * carries.\n *\n * A timeout keeps its own code, because \"the command never finished\" and \"the\n * command never started\" are different things to a caller deciding whether to\n * retry. Every other way of producing no exit code is a host failure.\n *\n * @category errors\n * @since 1.0.0\n */\nexport const toStdErrorCode = (error: ExecError): StdError.Code =>\n error.code === \"timeout\" ? \"timeout\" : \"command_failed\"\n\n/**\n * The model-facing failure one execution error becomes.\n *\n * A timeout names the command, which is what the caller asked for and all a\n * timeout has to say. Any other failure carries the message the execution\n * produced, which already names the command.\n *\n * @category errors\n * @since 1.0.0\n */\nexport const toStdError = (command: string, error: ExecError): StdError.StdError =>\n new StdError.StdError({\n code: toStdErrorCode(error),\n message: error.code === \"timeout\"\n ? `Command timed out: ${command}`\n : `Command failed to start: ${error.message}`,\n ...(error.limitMillis === undefined ? {} : { limitMillis: error.limitMillis })\n })\n"]}
1
+ {"version":3,"file":"Exec.js","sourceRoot":"","sources":["../../../src/internal/Exec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,uBAAuB,MAAM,wCAAwC,CAAA;AACjF,OAAO,KAAK,mBAAmB,MAAM,oCAAoC,CAAA;AACzE,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,YAAY,MAAM,6BAA6B,CAAA;AAC3D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAE1C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE,aAAa,EAAE,kBAAkB,CAAC,CAAC,CAAA;AAU5F;;;;;;;;;GASG;AACH,MAAM,OAAO,SAAU,SAAQ,MAAM,CAAC,WAAW,EAAa,CAAC,uBAAuB,EAAE;IACtF,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;CAC5C,CAAC;CAAG;AAmEL,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAA;AAExC;;;;;;;;GAQG;AACH,MAAM,UAAU,GAAG,CAAC,KAAW,EAAW,EAAE;IAC1C,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACzC,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACxB,MAAM,IAAI,KAAK,CAAC,UAAU,CAAA;IAC5B,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAA;IAChF,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,OAAO,KAAK,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAE,GAAG,WAAW,CAAC,KAAK,WAAW;QAAE,KAAK,EAAE,CAAA;IACtG,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,OAAO,GAAG,KAAK,EAAE,CAAA;AAC7F,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,CAClB,MAAoC,EACpC,QAAgB,EAChB,QAAuC,EACZ,EAAE,CAC7B,MAAM,CAAC,OAAO,CACZ,MAAM,EACN,GAAS,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAClD,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;IACf,IAAI,KAAK,CAAC,UAAU,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACxC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACxB,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAA;IAC/B,OAAO,KAAK,CAAC,KAAK,GAAG,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzD,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAA;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAA;QAC9B,IAAI,KAAK,CAAC,UAAU,IAAI,MAAM,EAAE,CAAC;YAC/B,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;YACpB,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAA;YAC/B,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,UAAU,CAAA;QACnC,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;YACxC,KAAK,CAAC,KAAK,IAAI,MAAM,CAAA;YACrB,KAAK,CAAC,OAAO,IAAI,MAAM,CAAA;QACzB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CACF,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAC1B,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC;IACxC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,CAAC,OAAO,EAAE;IAC3C,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CACtB,CAAC,CAAA;AAEJ,MAAM,OAAO,GAAG,CACd,MAAoC,EACpC,QAA4B,EAC5B,QAAuC,EACZ,EAAE,CAC7B,QAAQ,KAAK,SAAS;IACpB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/F,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;AAE7C,MAAM,SAAS,GAAG,CAChB,OAAe,EACf,OAAoB,EAC2D,EAAE,CACjF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,mBAAmB,CAAC,mBAAmB,CAAA;IAC9D,MAAM,QAAQ,GAAgC;QAC5C,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;QAC1D,GAAG,EAAE,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC;QAC3D,SAAS,EAAE,KAAK;QAChB,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS;YAC7B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;KACrE,CAAA;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CACjC,OAAO,CAAC,IAAI,KAAK,SAAS;QACxB,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC;QACtC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAC5D,CAAA;IACD,wEAAwE;IACxE,yEAAyE;IACzE,sEAAsE;IACtE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAClD;QACE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,EAAE,OAAO,CAAC,QAAQ,CAAC;QACjE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,EAAE,OAAO,CAAC,QAAQ,CAAC;QACjE,MAAM,CAAC,QAAQ;KAChB,EACD,EAAE,WAAW,EAAE,WAAW,EAAE,CAC7B,CAAA;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG;YACjB,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;YAC9C,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;SAC/C;aACE,MAAM,CAAC,CAAC,MAAM,EAAoB,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAA;QAC7D,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACvB,IAAI,SAAS,CAAC;gBACZ,IAAI,EAAE,kBAAkB;gBACxB,OAAO,EAAE,GAAG,OAAO,IACjB,UAAU,CAAC,IAAI,CAAC,OAAO,CACzB,iBAAiB,OAAO,CAAC,eAAe,4CAA4C;aACrF,CAAC,CACH,CAAA;QACH,CAAC;IACH,CAAC;IACD,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,IAAI;QACnB,MAAM,EAAE,MAAM,CAAC,IAAI;QACnB,QAAQ;QACR,kBAAkB,EAAE,MAAM,CAAC,YAAY;QACvC,kBAAkB,EAAE,MAAM,CAAC,YAAY;KACxC,CAAA;AACH,CAAC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CACxB,KAAK,YAAY,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;IACjD,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,SAAS,OAAO,KAAK,KAAK,CAAC,OAAO,EAAE;CAC9C,CAAC,CACH,CACF,CAAA;AAEH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAClB,OAAe,EACf,UAAuB,EAAE,EACsD,EAAE,CACjF,OAAO,CAAC,SAAS,KAAK,SAAS;IAC7B,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAC7B,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE;QAClD,QAAQ,EAAE,OAAO,CAAC,SAAS;QAC3B,MAAM,EAAE,GAAG,EAAE,CACX,MAAM,CAAC,IAAI,CACT,IAAI,SAAS,CAAC;YACZ,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,WAAW,OAAO,eAAe,OAAO,CAAC,SAAS,IAAI;YAC/D,WAAW,EAAE,OAAO,CAAC,SAAS;SAC/B,CAAC,CACH;KACJ,CAAC,CAAA;AAEN;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAgB,EAAiB,EAAE,CAChE,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAA;AAEzD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAe,EAAE,KAAgB,EAAqB,EAAE,CACjF,IAAI,QAAQ,CAAC,QAAQ,CAAC;IACpB,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC;IAC3B,OAAO,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS;QAC/B,CAAC,CAAC,sBAAsB,OAAO,EAAE;QACjC,CAAC,CAAC,4BAA4B,KAAK,CAAC,OAAO,EAAE;IAC/C,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC;CAC/E,CAAC,CAAA","sourcesContent":["/**\n * Buffered shell execution over the permission-aware process spawner.\n *\n * `@smthrs/kernel` used to expose a `Shell` service whose `exec` returned a\n * buffered `{ stdout, stderr, exitCode }`. The kernel replaced it with\n * `ChildProcessSpawner`, Effect's own process boundary, which streams and has\n * no buffered form. This module is the buffered form the shell flows still\n * want, expressed in terms of the spawner so the `proc:spawn` capability check\n * and the command-line resource stay exactly where the kernel put them.\n *\n * Commands run through the platform shell (`shell: true`), matching the old\n * service: the flows take a command *line*, not an argv.\n *\n * @since 1.0.0\n */\n\nimport * as ChildProcessEnvironment from \"@smthrs/kernel/ChildProcessEnvironment\"\nimport * as ChildProcessSpawner from \"@smthrs/kernel/ChildProcessSpawner\"\nimport * as Effect from \"effect/Effect\"\nimport * as ChildProcess from \"effect/process/ChildProcess\"\nimport * as Schema from \"effect/Schema\"\nimport * as Stream from \"effect/Stream\"\nimport * as StdError from \"../StdError.ts\"\n\n/**\n * Failure codes a buffered execution can report, matching the codes the\n * removed kernel `Shell` used so handler-level mapping is unchanged.\n *\n * @category models\n * @since 1.0.0\n */\nexport const ExecErrorCode = Schema.Literals([\"timeout\", \"spawn_error\", \"capture_overflow\"])\n\n/**\n * Failure codes a buffered execution can report.\n *\n * @category models\n * @since 1.0.0\n */\nexport type ExecErrorCode = typeof ExecErrorCode.Type\n\n/**\n * A command that never produced an exit code.\n *\n * A non-zero exit is a successful {@link ExecResult}, not a failure; this\n * error is reserved for a command that could not start or was cut off by its\n * timeout, or whose captured output exceeded a refusing capture bound.\n *\n * @category errors\n * @since 1.0.0\n */\nexport class ExecError extends Schema.TaggedError<ExecError>()(\"@smthrs/std/ExecError\", {\n code: ExecErrorCode,\n message: Schema.String,\n /** The limit a `timeout` ran past, in milliseconds. */\n limitMillis: Schema.optional(Schema.Number)\n}) {}\n\n/**\n * The buffered result of one command.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface ExecResult {\n readonly stdout: string\n readonly stderr: string\n readonly exitCode: number\n /** UTF-8 bytes dropped from the head of stdout to stay inside the capture bound. */\n readonly stdoutDroppedBytes: number\n /** UTF-8 bytes dropped from the head of stderr to stay inside the capture bound. */\n readonly stderrDroppedBytes: number\n}\n\n/**\n * Options accepted by {@link exec}.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface ExecOptions {\n readonly cwd?: string | undefined\n readonly env?: Readonly<Record<string, string>> | undefined\n readonly timeoutMs?: number | undefined\n /**\n * The program's arguments. Present means an argv, absent means a command\n * line for the platform shell. An argv is how a payload reaches a program\n * without being quoted into a string: nothing between here and `execve`\n * re-parses it.\n */\n readonly args?: ReadonlyArray<string> | undefined\n /**\n * Text written to the program's standard input, as data. A script delivered\n * this way is never quoted, escaped, or heredoc-terminated, which is the\n * whole point: quoting corruption cost the measured SWE-bench program twelve\n * probe failures and one instance's most expensive frame.\n */\n readonly stdin?: string | undefined\n /**\n * Bytes retained per captured stream. A stream that prints more keeps its\n * tail and reports what it dropped, so a command printing gigabytes costs a\n * bounded amount of memory rather than the whole of what it printed.\n *\n * Absent means unbounded, which is what a caller wants when it needs every\n * byte a tool produced (`rg --files`, `git worktree list`).\n */\n readonly maxCaptureBytes?: number | undefined\n /** Defaults to `tail`; `refuse` fails if either stream exceeds the bound. */\n readonly overflow?: \"tail\" | \"refuse\" | undefined\n}\n\n/** One captured stream: the text kept, and the bytes dropped to keep it bounded. */\ninterface Capture {\n readonly text: string\n readonly droppedBytes: number\n}\n\ninterface Tail {\n chunks: Array<Uint8Array>\n bytes: number\n dropped: number\n}\n\nconst decoder = new TextDecoder(\"utf-8\")\n\n/**\n * Joins the retained chunks and decodes them, skipping the partial code point a\n * dropped head can leave behind.\n *\n * A UTF-8 continuation byte is `10xxxxxx`, and a code point is at most four\n * bytes, so at most three leading continuation bytes can precede the first\n * whole character. Skipping them is counted as dropped rather than decoded to a\n * replacement character the process never printed.\n */\nconst decodeTail = (state: Tail): Capture => {\n const bytes = new Uint8Array(state.bytes)\n let offset = 0\n for (const chunk of state.chunks) {\n bytes.set(chunk, offset)\n offset += chunk.byteLength\n }\n if (state.dropped === 0) return { text: decoder.decode(bytes), droppedBytes: 0 }\n let start = 0\n while (start < bytes.byteLength && start < 3 && (bytes[start]! & 0b1100_0000) === 0b1000_0000) start++\n return { text: decoder.decode(bytes.subarray(start)), droppedBytes: state.dropped + start }\n}\n\nconst boundedTail = <E>(\n stream: Stream.Stream<Uint8Array, E>,\n maxBytes: number,\n overflow: \"tail\" | \"refuse\" | undefined\n): Effect.Effect<Capture, E> =>\n Stream.runFold(\n stream,\n (): Tail => ({ chunks: [], bytes: 0, dropped: 0 }),\n (state, chunk) => {\n if (chunk.byteLength === 0) return state\n state.chunks.push(chunk)\n state.bytes += chunk.byteLength\n while (state.bytes > maxBytes && state.chunks.length > 0) {\n const excess = state.bytes - maxBytes\n const first = state.chunks[0]!\n if (first.byteLength <= excess) {\n state.chunks.shift()\n state.bytes -= first.byteLength\n state.dropped += first.byteLength\n } else {\n state.chunks[0] = first.subarray(excess)\n state.bytes -= excess\n state.dropped += excess\n }\n }\n return state\n }\n ).pipe(Effect.map((state) =>\n overflow === \"refuse\" && state.dropped > 0\n ? { text: \"\", droppedBytes: state.dropped }\n : decodeTail(state)\n ))\n\nconst capture = <E>(\n stream: Stream.Stream<Uint8Array, E>,\n maxBytes: number | undefined,\n overflow: \"tail\" | \"refuse\" | undefined\n): Effect.Effect<Capture, E> =>\n maxBytes === undefined\n ? Effect.map(Stream.mkString(Stream.decodeText(stream)), (text) => ({ text, droppedBytes: 0 }))\n : boundedTail(stream, maxBytes, overflow)\n\nconst unbounded = (\n command: string,\n options: ExecOptions\n): Effect.Effect<ExecResult, ExecError, ChildProcessSpawner.ChildProcessSpawner> =>\n Effect.gen(function*() {\n const spawner = yield* ChildProcessSpawner.ChildProcessSpawner\n const settings: ChildProcess.CommandOptions = {\n ...(options.args === undefined ? { shell: true } : {}),\n ...(options.cwd === undefined ? {} : { cwd: options.cwd }),\n env: ChildProcessEnvironment.make(process.env, options.env),\n extendEnv: false,\n ...(options.stdin === undefined\n ? {}\n : { stdin: Stream.make(new TextEncoder().encode(options.stdin)) })\n }\n const handle = yield* spawner.spawn(\n options.args === undefined\n ? ChildProcess.make(command, settings)\n : ChildProcess.make(command, [...options.args], settings)\n )\n // stdout, stderr, and the exit code have to be consumed concurrently: a\n // command that fills a pipe blocks until the pipe is drained, so waiting\n // for exit first would deadlock on any output larger than the buffer.\n const [stdout, stderr, exitCode] = yield* Effect.all(\n [\n capture(handle.stdout, options.maxCaptureBytes, options.overflow),\n capture(handle.stderr, options.maxCaptureBytes, options.overflow),\n handle.exitCode\n ],\n { concurrency: \"unbounded\" }\n )\n if (options.overflow === \"refuse\") {\n const overflowed = [\n stdout.droppedBytes > 0 ? \"stdout\" : undefined,\n stderr.droppedBytes > 0 ? \"stderr\" : undefined\n ]\n .filter((stream): stream is string => stream !== undefined)\n if (overflowed.length > 0) {\n return yield* Effect.fail(\n new ExecError({\n code: \"capture_overflow\",\n message: `${command} ${\n overflowed.join(\" and \")\n } exceeded the ${options.maxCaptureBytes}-byte capture cap; refusing partial output`\n })\n )\n }\n }\n return {\n stdout: stdout.text,\n stderr: stderr.text,\n exitCode,\n stdoutDroppedBytes: stdout.droppedBytes,\n stderrDroppedBytes: stderr.droppedBytes\n }\n }).pipe(\n Effect.scoped,\n Effect.mapError((error) =>\n error instanceof ExecError ? error : new ExecError({\n code: \"spawn_error\",\n message: `exec: ${command}: ${error.message}`\n })\n )\n )\n\n/**\n * Runs a command line through the platform shell and buffers its output.\n *\n * Cancellation is scope closure: the spawn is scoped, so an interrupted fiber\n * — including the one a `timeoutMs` interrupts — terminates the process rather\n * than leaking it.\n *\n * @category execution\n * @since 1.0.0\n */\nexport const exec = (\n command: string,\n options: ExecOptions = {}\n): Effect.Effect<ExecResult, ExecError, ChildProcessSpawner.ChildProcessSpawner> =>\n options.timeoutMs === undefined\n ? unbounded(command, options)\n : Effect.timeoutOrElse(unbounded(command, options), {\n duration: options.timeoutMs,\n orElse: () =>\n Effect.fail(\n new ExecError({\n code: \"timeout\",\n message: `exec: \\`${command}\\` exceeded ${options.timeoutMs}ms`,\n limitMillis: options.timeoutMs\n })\n )\n })\n\n/**\n * The model-facing failure code a command that never produced an exit code\n * carries.\n *\n * A timeout keeps its own code, because \"the command never finished\" and \"the\n * command never started\" are different things to a caller deciding whether to\n * retry. Every other way of producing no exit code is a host failure.\n *\n * @category errors\n * @since 1.0.0\n */\nexport const toStdErrorCode = (error: ExecError): StdError.Code =>\n error.code === \"timeout\" ? \"timeout\" : \"command_failed\"\n\n/**\n * The model-facing failure one execution error becomes.\n *\n * A timeout names the command, which is what the caller asked for and all a\n * timeout has to say. Any other failure carries the message the execution\n * produced, which already names the command.\n *\n * @category errors\n * @since 1.0.0\n */\nexport const toStdError = (command: string, error: ExecError): StdError.StdError =>\n new StdError.StdError({\n code: toStdErrorCode(error),\n message: error.code === \"timeout\"\n ? `Command timed out: ${command}`\n : `Command failed to start: ${error.message}`,\n ...(error.limitMillis === undefined ? {} : { limitMillis: error.limitMillis })\n })\n"]}
@@ -6,9 +6,9 @@
6
6
  import type { GrantStore } from "@smthrs/kernel/GrantStore";
7
7
  import * as HttpClient from "@smthrs/kernel/HttpClient";
8
8
  import * as Effect from "effect/Effect";
9
+ import * as HttpClientRequest from "effect/http/HttpClientRequest";
9
10
  import * as Schema from "effect/Schema";
10
11
  import * as Stream from "effect/Stream";
11
- import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
12
12
  import * as StdError from "../StdError.ts";
13
13
  /**
14
14
  * Maximum captured response bytes before decoding.
@@ -1 +1 @@
1
- {"version":3,"file":"Http.d.ts","sourceRoot":"","sources":["../../../src/internal/Http.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,UAAU,MAAM,2BAA2B,CAAA;AACvD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,iBAAiB,MAAM,wCAAwC,CAAA;AAC3E,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAK1C;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,QAAkB,CAAA;AAOjD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,CAAC,EAC9B,QAAQ,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,EACvC,KAAK,MAAM,KACV,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC,CA6BlD,CAAA;AAEH;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,EAAE,OAAO,OAAO,KAAG,QAAQ,CAAC,QAIhE,CAAA;AAEJ;;;;;GAKG;AACH,eAAO,MAAM,MAAM,GAAI,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,EAAE,MAAM,MAAM,KAAG,MAAM,GAAG,SAGrG,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,OAAO,eAAkE,CAAA;AAEtF;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAClC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9B,KAAK,MAAM,EACX,gBAAY,EACZ,eAAe,CAAC,OAAO,EAAE,MAAM,KAAK,QAAQ,CAAC,QAAQ,KACpD,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAsB3C,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GACpB,MAAM,MAAM,KACX;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAShF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ;;;;;EAKnB,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,OAAO;kBAEF,MAAM;uBACD,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS;uBAC5C,MAAM,GAAG,SAAS;sBAEpB,MAAM,KAAK,iBAAiB,CAAC,iBAAiB;;;;;yDA2BjE,CAAA"}
1
+ {"version":3,"file":"Http.d.ts","sourceRoot":"","sources":["../../../src/internal/Http.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,UAAU,MAAM,2BAA2B,CAAA;AACvD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,iBAAiB,MAAM,+BAA+B,CAAA;AAClE,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAK1C;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,QAAkB,CAAA;AAOjD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,CAAC,EAC9B,QAAQ,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,EACvC,KAAK,MAAM,KACV,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC,CA6BlD,CAAA;AAEH;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,EAAE,OAAO,OAAO,KAAG,QAAQ,CAAC,QAIhE,CAAA;AAEJ;;;;;GAKG;AACH,eAAO,MAAM,MAAM,GAAI,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,EAAE,MAAM,MAAM,KAAG,MAAM,GAAG,SAGrG,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,OAAO,eAAkE,CAAA;AAEtF;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAClC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9B,KAAK,MAAM,EACX,gBAAY,EACZ,eAAe,CAAC,OAAO,EAAE,MAAM,KAAK,QAAQ,CAAC,QAAQ,KACpD,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAsB3C,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GACpB,MAAM,MAAM,KACX;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAShF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ;;;;;EAKnB,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,OAAO;kBAEF,MAAM;uBACD,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS;uBAC5C,MAAM,GAAG,SAAS;sBAEpB,MAAM,KAAK,iBAAiB,CAAC,iBAAiB;;;;;yDA2BjE,CAAA"}
@@ -5,9 +5,9 @@
5
5
  */
6
6
  import * as HttpClient from "@smthrs/kernel/HttpClient";
7
7
  import * as Effect from "effect/Effect";
8
+ import * as HttpClientRequest from "effect/http/HttpClientRequest";
8
9
  import * as Schema from "effect/Schema";
9
10
  import * as Stream from "effect/Stream";
10
- import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
11
11
  import * as StdError from "../StdError.js";
12
12
  import { guarded, refusal } from "./HttpNetwork.js";
13
13
  import { MAX_OUTPUT_BYTES, notice, truncateBytes } from "./Text.js";
@@ -1 +1 @@
1
- {"version":3,"file":"Http.js","sourceRoot":"","sources":["../../../src/internal/Http.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,UAAU,MAAM,2BAA2B,CAAA;AACvD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,iBAAiB,MAAM,wCAAwC,CAAA;AAC3E,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAEvC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAA;AAOjD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,MAAuC,EACvC,GAAW,EAC0C,EAAE,CACvD,MAAM,CAAC,aAAa,CAClB,MAAM,EACN,GAAc,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAC1C,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;IACf,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,UAAU,CAAA;IAC1C,IAAI,IAAI,GAAG,kBAAkB,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,IAAI,CAChB,IAAI,QAAQ,CAAC,QAAQ,CAAC;YACpB,IAAI,EAAE,oBAAoB;YAC1B,OAAO,EAAE,kCAAkC;YAC3C,IAAI,EAAE,GAAG;SACV,CAAC,CACH,CAAA;IACH,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACxB,KAAK,CAAC,IAAI,GAAG,IAAI,CAAA;IACjB,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC9B,CAAC,CACF,CAAC,IAAI,CACJ,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;IACnB,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACzC,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACzB,MAAM,IAAI,KAAK,CAAC,UAAU,CAAA;IAC5B,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAC,CACH,CAAA;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAW,EAAE,KAAc,EAAqB,EAAE,CAC7E,KAAK,YAAY,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC;IACnF,IAAI,EAAE,gBAAgB;IACtB,OAAO,EAAE,mBAAmB,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;CACxF,CAAC,CAAA;AAEJ;;;;;GAKG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,OAAqD,EAAE,IAAY,EAAsB,EAAE;IAChH,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;IAChC,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AAClF,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;AAEtF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,MAA8B,EAC9B,GAAW,EACX,OAAO,GAAG,EAAE,EACZ,YAAqD,EACT,EAAE;IAC9C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;QACjC,OAAO,MAAM,CAAC,IAAI,CAChB,IAAI,QAAQ,CAAC,QAAQ,CAAC;YACpB,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,2DAA2D;YACpE,IAAI,EAAE,GAAG;SACV,CAAC,CACH,CAAA;IACH,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;IACtC,OAAO,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE;QAClC,QAAQ,EAAE,OAAO,GAAG,KAAK;QACzB,MAAM,EAAE,GAAG,EAAE,CACX,MAAM,CAAC,IAAI,CACT,YAAY,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC;YAC/C,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,2BAA2B,OAAO,UAAU;YACrD,IAAI,EAAE,GAAG;SACV,CAAC,CACH;KACJ,CAAC,CAAA;AACJ,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,IAAY,EACsE,EAAE;IACpF,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,EAAE,gBAAgB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;IACxE,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,GAAG,CAAC,QAAQ,CAAC,SAAS;YACpB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,SAAS,GAAG,QAAQ,CAAC,YAAY,CAAC,EAAE;YAC7F,CAAC,CAAC,EAAE,CAAC;KACR,CAAA;AACH,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,4CAA4C,EAAE,CAAC;IAC7F,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,uBAAuB,EAAE,CAAC;IACtE,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,8CAA8C,EAAE,CAAC;IACnG,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,uBAAuB,EAAE,CAAC,CAAC;CAC1F,CAAC,CAAA;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,EACxD,KAIC,EACD,WAAiE;IAEjE,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACnC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACvB,IAAI,QAAQ,CAAC,QAAQ,CAAC;YACpB,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,wDAAwD,KAAK,CAAC,GAAG,EAAE;YAC5E,IAAI,EAAE,KAAK,CAAC,GAAG;SAChB,CAAC,CACH,CAAA;IACH,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;IACpD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC3C,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,YAAY,CAC3C,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CACpC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAC7F,CAAA;QACD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;QAC5D,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,CAAA;IAC3C,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,EACnE,KAAK,CAAC,GAAG,EACT,KAAK,CAAC,OAAO,CACd,CAAA;IACD,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,EAAE,GAAG,SAAS,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;IAC1E,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,UAAU,EAAE,CAAA;AAC9C,CAAC,CAAC,CAAA","sourcesContent":["/**\n * Shared HTTP response limits, error mapping, and request deadlines.\n *\n * @since 1.0.0\n */\n\nimport type { GrantStore } from \"@smthrs/kernel/GrantStore\"\nimport * as HttpClient from \"@smthrs/kernel/HttpClient\"\nimport * as Effect from \"effect/Effect\"\nimport * as Schema from \"effect/Schema\"\nimport * as Stream from \"effect/Stream\"\nimport * as HttpClientRequest from \"effect/unstable/http/HttpClientRequest\"\nimport * as StdError from \"../StdError.ts\"\nimport { guarded, refusal } from \"./HttpNetwork.ts\"\nimport { MAX_OUTPUT_BYTES, notice, truncateBytes } from \"./Text.ts\"\nimport { parseHttpUrl } from \"./Url.ts\"\n\n/**\n * Maximum captured response bytes before decoding.\n *\n * @category http\n * @since 1.0.0\n */\nexport const MAX_RESPONSE_BYTES = 5 * 1024 * 1024\n\ninterface BodyState {\n readonly chunks: Array<Uint8Array>\n size: number\n}\n\n/**\n * Reads a response up to the shared byte limit and finalizes the stream on failure.\n *\n * @category http\n * @since 1.0.0\n */\nexport const readBounded = <E, R>(\n stream: Stream.Stream<Uint8Array, E, R>,\n url: string\n): Effect.Effect<Uint8Array, E | StdError.StdError, R> =>\n Stream.runFoldEffect(\n stream,\n (): BodyState => ({ chunks: [], size: 0 }),\n (state, chunk) => {\n const size = state.size + chunk.byteLength\n if (size > MAX_RESPONSE_BYTES) {\n return Effect.fail(\n new StdError.StdError({\n code: \"response_too_large\",\n message: \"Response exceeds the 5 MiB limit\",\n path: url\n })\n )\n }\n state.chunks.push(chunk)\n state.size = size\n return Effect.succeed(state)\n }\n ).pipe(\n Effect.map((state) => {\n const output = new Uint8Array(state.size)\n let offset = 0\n for (const chunk of state.chunks) {\n output.set(chunk, offset)\n offset += chunk.byteLength\n }\n return output\n })\n )\n\n/**\n * Maps transport failures while preserving standard HTTP failure codes.\n *\n * @category http\n * @since 1.0.0\n */\nexport const requestError = (url: string, error: unknown): StdError.StdError =>\n error instanceof StdError.StdError ? error : refusal(error) ?? new StdError.StdError({\n code: \"request_failed\",\n message: `Request failed: ${url}${error instanceof Error ? ` (${error.message})` : \"\"}`\n })\n\n/**\n * Looks up a response header without depending on transport normalization.\n *\n * @category http\n * @since 1.0.0\n */\nexport const header = (headers: Readonly<Record<string, string | undefined>>, name: string): string | undefined => {\n const lower = name.toLowerCase()\n return Object.entries(headers).find(([key]) => key.toLowerCase() === lower)?.[1]\n}\n\n/**\n * Seconds; the runtime caps valid overrides at 120.\n *\n * @category http\n * @since 1.0.0\n */\nexport const Timeout = Schema.Number.check(Schema.isFinite(), Schema.isGreaterThan(0))\n\n/**\n * Bounds the entire request and body read with one timer. Interruption reaches\n * HttpClient.execute and response.stream so Effect aborts the transport and\n * finalizes the body reader before returning the timeout failure.\n * `timeoutError` preserves a tool's own timeout message while sharing the\n * validation, duration cap, and interruption behavior.\n *\n * @category http\n * @since 1.0.0\n */\nexport const withDeadline = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n url: string,\n timeout = 30,\n timeoutError?: (seconds: number) => StdError.StdError\n): Effect.Effect<A, E | StdError.StdError, R> => {\n if (!Schema.is(Timeout)(timeout)) {\n return Effect.fail(\n new StdError.StdError({\n code: \"invalid_input\",\n message: \"Timeout must be a finite number greater than zero seconds\",\n path: url\n })\n )\n }\n const seconds = Math.min(timeout, 120)\n return Effect.timeoutOrElse(effect, {\n duration: seconds * 1_000,\n orElse: () =>\n Effect.fail(\n timeoutError?.(seconds) ?? new StdError.StdError({\n code: \"timeout\",\n message: `Request timed out after ${seconds} seconds`,\n path: url\n })\n )\n })\n}\n\n/**\n * Keeps the head of rendered response text within the shared output budget and\n * discloses the cut.\n *\n * @since 1.0.0\n * @private\n */\nexport const capOutput = (\n text: string\n): { readonly text: string; readonly truncated: boolean; readonly notice?: string } => {\n const rendered = truncateBytes(text, MAX_OUTPUT_BYTES, { keep: \"head\" })\n return {\n text: rendered.text,\n truncated: rendered.truncated,\n ...(rendered.truncated\n ? { notice: notice(\"bytes\", rendered.keptBytes, rendered.keptBytes + rendered.droppedBytes) }\n : {})\n }\n}\n\n/** Shared response contract for the GET and POST tools.\n * @since 1.0.0\n * @private\n */\nexport const Response = Schema.Struct({\n status: Schema.Number.annotate({ description: \"HTTP status code, including error statuses\" }),\n body: Schema.String.annotate({ description: \"Response body as text\" }),\n truncated: Schema.Boolean.annotate({ description: \"Whether the body exceeded the display budget\" }),\n notice: Schema.optional(Schema.String.annotate({ description: \"Truncation disclosure\" }))\n})\n\n/** Validate, execute, and render one bounded HTTP request.\n * @since 1.0.0\n * @private\n */\nexport const execute = Effect.fn(\"Http.execute\")(function*(\n input: {\n readonly url: string\n readonly headers?: Readonly<Record<string, string>> | undefined\n readonly timeout?: number | undefined\n },\n makeRequest: (url: string) => HttpClientRequest.HttpClientRequest\n): Effect.fn.Return<typeof Response.Type, StdError.StdError, HttpClient.HttpClient | GrantStore> {\n const url = parseHttpUrl(input.url)\n if (url === undefined) {\n return yield* Effect.fail(\n new StdError.StdError({\n code: \"invalid_input\",\n message: `URL must use http or https without user information: ${input.url}`,\n path: input.url\n })\n )\n }\n const client = guarded(yield* HttpClient.HttpClient)\n const request = makeRequest(url.toString())\n const { status, bytes } = yield* withDeadline(\n Effect.gen(function*() {\n const response = yield* client.execute(\n input.headers === undefined ? request : HttpClientRequest.setHeaders(request, input.headers)\n )\n const bytes = yield* readBounded(response.stream, input.url)\n return { status: response.status, bytes }\n }).pipe(Effect.mapError((error) => requestError(input.url, error))),\n input.url,\n input.timeout\n )\n const { text, ...disclosure } = capOutput(new TextDecoder().decode(bytes))\n return { status, body: text, ...disclosure }\n})\n"]}
1
+ {"version":3,"file":"Http.js","sourceRoot":"","sources":["../../../src/internal/Http.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared HTTP response limits, error mapping, and request deadlines.\n *\n * @since 1.0.0\n */\n\nimport type { GrantStore } from \"@smthrs/kernel/GrantStore\"\nimport * as HttpClient from \"@smthrs/kernel/HttpClient\"\nimport * as Effect from \"effect/Effect\"\nimport * as HttpClientRequest from \"effect/http/HttpClientRequest\"\nimport * as Schema from \"effect/Schema\"\nimport * as Stream from \"effect/Stream\"\nimport * as StdError from \"../StdError.ts\"\nimport { guarded, refusal } from \"./HttpNetwork.ts\"\nimport { MAX_OUTPUT_BYTES, notice, truncateBytes } from \"./Text.ts\"\nimport { parseHttpUrl } from \"./Url.ts\"\n\n/**\n * Maximum captured response bytes before decoding.\n *\n * @category http\n * @since 1.0.0\n */\nexport const MAX_RESPONSE_BYTES = 5 * 1024 * 1024\n\ninterface BodyState {\n readonly chunks: Array<Uint8Array>\n size: number\n}\n\n/**\n * Reads a response up to the shared byte limit and finalizes the stream on failure.\n *\n * @category http\n * @since 1.0.0\n */\nexport const readBounded = <E, R>(\n stream: Stream.Stream<Uint8Array, E, R>,\n url: string\n): Effect.Effect<Uint8Array, E | StdError.StdError, R> =>\n Stream.runFoldEffect(\n stream,\n (): BodyState => ({ chunks: [], size: 0 }),\n (state, chunk) => {\n const size = state.size + chunk.byteLength\n if (size > MAX_RESPONSE_BYTES) {\n return Effect.fail(\n new StdError.StdError({\n code: \"response_too_large\",\n message: \"Response exceeds the 5 MiB limit\",\n path: url\n })\n )\n }\n state.chunks.push(chunk)\n state.size = size\n return Effect.succeed(state)\n }\n ).pipe(\n Effect.map((state) => {\n const output = new Uint8Array(state.size)\n let offset = 0\n for (const chunk of state.chunks) {\n output.set(chunk, offset)\n offset += chunk.byteLength\n }\n return output\n })\n )\n\n/**\n * Maps transport failures while preserving standard HTTP failure codes.\n *\n * @category http\n * @since 1.0.0\n */\nexport const requestError = (url: string, error: unknown): StdError.StdError =>\n error instanceof StdError.StdError ? error : refusal(error) ?? new StdError.StdError({\n code: \"request_failed\",\n message: `Request failed: ${url}${error instanceof Error ? ` (${error.message})` : \"\"}`\n })\n\n/**\n * Looks up a response header without depending on transport normalization.\n *\n * @category http\n * @since 1.0.0\n */\nexport const header = (headers: Readonly<Record<string, string | undefined>>, name: string): string | undefined => {\n const lower = name.toLowerCase()\n return Object.entries(headers).find(([key]) => key.toLowerCase() === lower)?.[1]\n}\n\n/**\n * Seconds; the runtime caps valid overrides at 120.\n *\n * @category http\n * @since 1.0.0\n */\nexport const Timeout = Schema.Number.check(Schema.isFinite(), Schema.isGreaterThan(0))\n\n/**\n * Bounds the entire request and body read with one timer. Interruption reaches\n * HttpClient.execute and response.stream so Effect aborts the transport and\n * finalizes the body reader before returning the timeout failure.\n * `timeoutError` preserves a tool's own timeout message while sharing the\n * validation, duration cap, and interruption behavior.\n *\n * @category http\n * @since 1.0.0\n */\nexport const withDeadline = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n url: string,\n timeout = 30,\n timeoutError?: (seconds: number) => StdError.StdError\n): Effect.Effect<A, E | StdError.StdError, R> => {\n if (!Schema.is(Timeout)(timeout)) {\n return Effect.fail(\n new StdError.StdError({\n code: \"invalid_input\",\n message: \"Timeout must be a finite number greater than zero seconds\",\n path: url\n })\n )\n }\n const seconds = Math.min(timeout, 120)\n return Effect.timeoutOrElse(effect, {\n duration: seconds * 1_000,\n orElse: () =>\n Effect.fail(\n timeoutError?.(seconds) ?? new StdError.StdError({\n code: \"timeout\",\n message: `Request timed out after ${seconds} seconds`,\n path: url\n })\n )\n })\n}\n\n/**\n * Keeps the head of rendered response text within the shared output budget and\n * discloses the cut.\n *\n * @since 1.0.0\n * @private\n */\nexport const capOutput = (\n text: string\n): { readonly text: string; readonly truncated: boolean; readonly notice?: string } => {\n const rendered = truncateBytes(text, MAX_OUTPUT_BYTES, { keep: \"head\" })\n return {\n text: rendered.text,\n truncated: rendered.truncated,\n ...(rendered.truncated\n ? { notice: notice(\"bytes\", rendered.keptBytes, rendered.keptBytes + rendered.droppedBytes) }\n : {})\n }\n}\n\n/** Shared response contract for the GET and POST tools.\n * @since 1.0.0\n * @private\n */\nexport const Response = Schema.Struct({\n status: Schema.Number.annotate({ description: \"HTTP status code, including error statuses\" }),\n body: Schema.String.annotate({ description: \"Response body as text\" }),\n truncated: Schema.Boolean.annotate({ description: \"Whether the body exceeded the display budget\" }),\n notice: Schema.optional(Schema.String.annotate({ description: \"Truncation disclosure\" }))\n})\n\n/** Validate, execute, and render one bounded HTTP request.\n * @since 1.0.0\n * @private\n */\nexport const execute = Effect.fn(\"Http.execute\")(function*(\n input: {\n readonly url: string\n readonly headers?: Readonly<Record<string, string>> | undefined\n readonly timeout?: number | undefined\n },\n makeRequest: (url: string) => HttpClientRequest.HttpClientRequest\n): Effect.fn.Return<typeof Response.Type, StdError.StdError, HttpClient.HttpClient | GrantStore> {\n const url = parseHttpUrl(input.url)\n if (url === undefined) {\n return yield* Effect.fail(\n new StdError.StdError({\n code: \"invalid_input\",\n message: `URL must use http or https without user information: ${input.url}`,\n path: input.url\n })\n )\n }\n const client = guarded(yield* HttpClient.HttpClient)\n const request = makeRequest(url.toString())\n const { status, bytes } = yield* withDeadline(\n Effect.gen(function*() {\n const response = yield* client.execute(\n input.headers === undefined ? request : HttpClientRequest.setHeaders(request, input.headers)\n )\n const bytes = yield* readBounded(response.stream, input.url)\n return { status: response.status, bytes }\n }).pipe(Effect.mapError((error) => requestError(input.url, error))),\n input.url,\n input.timeout\n )\n const { text, ...disclosure } = capOutput(new TextDecoder().decode(bytes))\n return { status, body: text, ...disclosure }\n})\n"]}
@@ -5,8 +5,8 @@
5
5
  */
6
6
  import { GrantStore } from "@smthrs/kernel/GrantStore";
7
7
  import { Context, Effect } from "effect";
8
- import * as HttpClient from "effect/unstable/http/HttpClient";
9
- import * as HttpClientError from "effect/unstable/http/HttpClientError";
8
+ import * as HttpClient from "effect/http/HttpClient";
9
+ import * as HttpClientError from "effect/http/HttpClientError";
10
10
  import * as StdError from "../StdError.ts";
11
11
  /** Resolver seam: all addresses must be public before an unprivileged request.
12
12
  * @since 1.0.0
@@ -1 +1 @@
1
- {"version":3,"file":"HttpNetwork.d.ts","sourceRoot":"","sources":["../../../src/internal/HttpNetwork.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAOtD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAA;AAEhD,OAAO,KAAK,UAAU,MAAM,iCAAiC,CAAA;AAC7D,OAAO,KAAK,eAAe,MAAM,sCAAsC,CAAA;AAGvE,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAG1C;;;GAGG;AACH,eAAO,MAAM,WAAW,+BACX,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAInE,CAAA;AAwEF;;;;GAIG;AACH,eAAO,MAAM,OAAO,GAClB,QAAQ,UAAU,CAAC,UAAU,EAC7B,gBAAa,KACZ,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,eAAe,EAAE,UAAU,CAuBxE,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,OAAO,GAAI,OAAO,OAAO,KAAG,QAAQ,CAAC,QAAQ,GAAG,SAW5D,CAAA"}
1
+ {"version":3,"file":"HttpNetwork.d.ts","sourceRoot":"","sources":["../../../src/internal/HttpNetwork.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAOtD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAA;AAEhD,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAA;AACpD,OAAO,KAAK,eAAe,MAAM,6BAA6B,CAAA;AAG9D,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAG1C;;;GAGG;AACH,eAAO,MAAM,WAAW,+BACX,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAInE,CAAA;AAwEF;;;;GAIG;AACH,eAAO,MAAM,OAAO,GAClB,QAAQ,UAAU,CAAC,UAAU,EAC7B,gBAAa,KACZ,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,eAAe,EAAE,UAAU,CAuBxE,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,OAAO,GAAI,OAAO,OAAO,KAAG,QAAQ,CAAC,QAAQ,GAAG,SAW5D,CAAA"}
@@ -7,9 +7,9 @@ import * as Capability from "@smthrs/capability/Capability";
7
7
  import { GrantStore } from "@smthrs/kernel/GrantStore";
8
8
  import { authorizePreflight, Destination, fromHttpClientError, supportsDestinationPinning } from "@smthrs/kernel/HttpClient";
9
9
  import { Context, Effect, Option } from "effect";
10
- import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
11
- import * as HttpClient from "effect/unstable/http/HttpClient";
12
- import * as HttpClientError from "effect/unstable/http/HttpClientError";
10
+ import * as FetchHttpClient from "effect/http/FetchHttpClient";
11
+ import * as HttpClient from "effect/http/HttpClient";
12
+ import * as HttpClientError from "effect/http/HttpClientError";
13
13
  import { lookup } from "node:dns/promises";
14
14
  import { BlockList, isIP } from "node:net";
15
15
  import * as StdError from "../StdError.js";
@@ -1 +1 @@
1
- {"version":3,"file":"HttpNetwork.js","sourceRoot":"","sources":["../../../src/internal/HttpNetwork.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Destination policy shared by the web tools, including every redirect hop.\n *\n * @since 1.0.0\n */\n\nimport * as Capability from \"@smthrs/capability/Capability\"\nimport { GrantStore } from \"@smthrs/kernel/GrantStore\"\nimport {\n authorizePreflight,\n Destination,\n fromHttpClientError,\n supportsDestinationPinning\n} from \"@smthrs/kernel/HttpClient\"\nimport { Context, Effect, Option } from \"effect\"\nimport * as FetchHttpClient from \"effect/unstable/http/FetchHttpClient\"\nimport * as HttpClient from \"effect/unstable/http/HttpClient\"\nimport * as HttpClientError from \"effect/unstable/http/HttpClientError\"\nimport { lookup } from \"node:dns/promises\"\nimport { BlockList, isIP } from \"node:net\"\nimport * as StdError from \"../StdError.ts\"\nimport { parseHttpUrl } from \"./Url.ts\"\n\n/** Resolver seam: all addresses must be public before an unprivileged request.\n * @since 1.0.0\n * @private\n */\nexport const ResolveHost = Context.Reference<\n (hostname: string) => Effect.Effect<ReadonlyArray<string>, unknown>\n>(\"@smthrs/std/HttpNetwork/ResolveHost\", {\n defaultValue: () => (hostname) =>\n Effect.tryPromise(async () => (await lookup(hostname, { all: true })).map((a) => a.address))\n})\n\nconst blocked = new BlockList()\nfor (\n const [address, prefix] of [\n [\"0.0.0.0\", 8],\n [\"10.0.0.0\", 8],\n [\"127.0.0.0\", 8],\n [\"169.254.0.0\", 16],\n [\"172.16.0.0\", 12],\n [\"192.168.0.0\", 16],\n [\"192.0.0.0\", 24],\n [\"100.64.0.0\", 10],\n [\"198.18.0.0\", 15],\n [\"224.0.0.0\", 4],\n [\"240.0.0.0\", 4]\n ] as const\n) blocked.addSubnet(address, prefix, \"ipv4\")\n// Allow global IPv6 and mapped IPv4 only, excluding transition tunnels.\nconst publicV6 = new BlockList()\npublicV6.addSubnet(\"2000::\", 3, \"ipv6\")\npublicV6.addSubnet(\"::ffff:0:0\", 96, \"ipv6\")\nblocked.addSubnet(\"2002::\", 16, \"ipv6\")\nblocked.addSubnet(\"2001::\", 32, \"ipv6\")\n\nconst isPublic = (address: string): boolean => {\n const family = isIP(address)\n if (family === 4) return !blocked.check(address, \"ipv4\")\n return family === 6 && publicV6.check(address, \"ipv6\") && !blocked.check(address, \"ipv6\")\n}\n\nconst failure = (code: StdError.Code, message: string, path: string) => new StdError.StdError({ code, message, path })\n\nconst check = Effect.fn(\"HttpNetwork.check\")(function*(value: string, client: HttpClient.HttpClient) {\n const url = parseHttpUrl(value)\n if (url === undefined) {\n return yield* Effect.fail(failure(\"invalid_input\", \"URL must use http or https without user information\", value))\n }\n if (!supportsDestinationPinning(client)) {\n return yield* Effect.fail(failure(\"unsupported\", \"HTTP host must support destination pinning\", value))\n }\n const hostname = url.hostname.replace(/^\\[|\\]$/g, \"\")\n const local = hostname.replace(/\\.$/, \"\").toLowerCase()\n const literal = isIP(hostname) !== 0\n const localhost = local === \"localhost\" || local.endsWith(\".localhost\")\n const resolve = yield* ResolveHost\n // Refuse localhost before DNS unless the origin is explicitly authorized.\n const privateGrant = Effect.gen(function*() {\n const store = yield* GrantStore\n const capability = yield* Effect.try({\n try: () => Capability.make(\"net:private\", url.origin),\n catch: () => failure(\"invalid_input\", \"Private HTTP origin exceeds the capability resource limit\", value)\n })\n yield* store.check(capability).pipe(\n Effect.mapError(() =>\n failure(\"permission_denied\", \"Private HTTP destination requires a net:private grant\", value)\n )\n )\n })\n if (localhost) yield* privateGrant\n const addresses = literal ? [hostname] : [\n ...yield* resolve(hostname).pipe(\n Effect.mapError(() => failure(\"request_failed\", \"Could not resolve HTTP destination\", value))\n )\n ]\n if (addresses.length === 0 || addresses.some((address) => isIP(address) === 0)) {\n return yield* Effect.fail(failure(\"request_failed\", \"HTTP destination has no valid addresses\", value))\n }\n if (!localhost && !addresses.every(isPublic)) yield* privateGrant\n return Object.freeze({ origin: url.origin, addresses: Object.freeze(addresses) })\n})\n\n/** Decorates the supplied client before following redirects through the guard.\n * The transport must honor manual redirects, as required by the kernel client.\n * @since 1.0.0\n * @private\n */\nexport const guarded = (\n client: HttpClient.HttpClient,\n follow = true\n): HttpClient.HttpClient.With<HttpClientError.HttpClientError, GrantStore> => {\n const checked = HttpClient.transform(\n client,\n (execute, request) =>\n authorizePreflight(\n request,\n check(request.url, client).pipe(\n Effect.mapError((cause) =>\n new HttpClientError.HttpClientError({\n reason: new HttpClientError.TransportError({ request, cause, description: cause.message })\n })\n ),\n Effect.flatMap((destination) =>\n Effect.updateContext(execute, (context: Context.Context<never>) =>\n Context.add(Context.add(context, Destination, destination), FetchHttpClient.RequestInit, {\n ...Context.getOrUndefined(context, FetchHttpClient.RequestInit),\n redirect: \"manual\"\n }))\n )\n )\n )\n )\n return follow ? HttpClient.followRedirects(checked) : checked\n}\n\n/** Recovers the typed refusal carried through Effect's HTTP error channel.\n * @since 1.0.0\n * @private\n */\nexport const refusal = (error: unknown): StdError.StdError | undefined => {\n if (!(error instanceof HttpClientError.HttpClientError) || error.reason._tag !== \"TransportError\") return undefined\n if (error.reason.cause instanceof StdError.StdError) return error.reason.cause\n if (Option.isSome(fromHttpClientError(error))) {\n return failure(\n \"permission_denied\",\n error.reason.description ?? \"HTTP permission was refused\",\n error.reason.request.url\n )\n }\n return undefined\n}\n"]}
1
+ {"version":3,"file":"HttpNetwork.js","sourceRoot":"","sources":["../../../src/internal/HttpNetwork.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Destination policy shared by the web tools, including every redirect hop.\n *\n * @since 1.0.0\n */\n\nimport * as Capability from \"@smthrs/capability/Capability\"\nimport { GrantStore } from \"@smthrs/kernel/GrantStore\"\nimport {\n authorizePreflight,\n Destination,\n fromHttpClientError,\n supportsDestinationPinning\n} from \"@smthrs/kernel/HttpClient\"\nimport { Context, Effect, Option } from \"effect\"\nimport * as FetchHttpClient from \"effect/http/FetchHttpClient\"\nimport * as HttpClient from \"effect/http/HttpClient\"\nimport * as HttpClientError from \"effect/http/HttpClientError\"\nimport { lookup } from \"node:dns/promises\"\nimport { BlockList, isIP } from \"node:net\"\nimport * as StdError from \"../StdError.ts\"\nimport { parseHttpUrl } from \"./Url.ts\"\n\n/** Resolver seam: all addresses must be public before an unprivileged request.\n * @since 1.0.0\n * @private\n */\nexport const ResolveHost = Context.Reference<\n (hostname: string) => Effect.Effect<ReadonlyArray<string>, unknown>\n>(\"@smthrs/std/HttpNetwork/ResolveHost\", {\n defaultValue: () => (hostname) =>\n Effect.tryPromise(async () => (await lookup(hostname, { all: true })).map((a) => a.address))\n})\n\nconst blocked = new BlockList()\nfor (\n const [address, prefix] of [\n [\"0.0.0.0\", 8],\n [\"10.0.0.0\", 8],\n [\"127.0.0.0\", 8],\n [\"169.254.0.0\", 16],\n [\"172.16.0.0\", 12],\n [\"192.168.0.0\", 16],\n [\"192.0.0.0\", 24],\n [\"100.64.0.0\", 10],\n [\"198.18.0.0\", 15],\n [\"224.0.0.0\", 4],\n [\"240.0.0.0\", 4]\n ] as const\n) blocked.addSubnet(address, prefix, \"ipv4\")\n// Allow global IPv6 and mapped IPv4 only, excluding transition tunnels.\nconst publicV6 = new BlockList()\npublicV6.addSubnet(\"2000::\", 3, \"ipv6\")\npublicV6.addSubnet(\"::ffff:0:0\", 96, \"ipv6\")\nblocked.addSubnet(\"2002::\", 16, \"ipv6\")\nblocked.addSubnet(\"2001::\", 32, \"ipv6\")\n\nconst isPublic = (address: string): boolean => {\n const family = isIP(address)\n if (family === 4) return !blocked.check(address, \"ipv4\")\n return family === 6 && publicV6.check(address, \"ipv6\") && !blocked.check(address, \"ipv6\")\n}\n\nconst failure = (code: StdError.Code, message: string, path: string) => new StdError.StdError({ code, message, path })\n\nconst check = Effect.fn(\"HttpNetwork.check\")(function*(value: string, client: HttpClient.HttpClient) {\n const url = parseHttpUrl(value)\n if (url === undefined) {\n return yield* Effect.fail(failure(\"invalid_input\", \"URL must use http or https without user information\", value))\n }\n if (!supportsDestinationPinning(client)) {\n return yield* Effect.fail(failure(\"unsupported\", \"HTTP host must support destination pinning\", value))\n }\n const hostname = url.hostname.replace(/^\\[|\\]$/g, \"\")\n const local = hostname.replace(/\\.$/, \"\").toLowerCase()\n const literal = isIP(hostname) !== 0\n const localhost = local === \"localhost\" || local.endsWith(\".localhost\")\n const resolve = yield* ResolveHost\n // Refuse localhost before DNS unless the origin is explicitly authorized.\n const privateGrant = Effect.gen(function*() {\n const store = yield* GrantStore\n const capability = yield* Effect.try({\n try: () => Capability.make(\"net:private\", url.origin),\n catch: () => failure(\"invalid_input\", \"Private HTTP origin exceeds the capability resource limit\", value)\n })\n yield* store.check(capability).pipe(\n Effect.mapError(() =>\n failure(\"permission_denied\", \"Private HTTP destination requires a net:private grant\", value)\n )\n )\n })\n if (localhost) yield* privateGrant\n const addresses = literal ? [hostname] : [\n ...yield* resolve(hostname).pipe(\n Effect.mapError(() => failure(\"request_failed\", \"Could not resolve HTTP destination\", value))\n )\n ]\n if (addresses.length === 0 || addresses.some((address) => isIP(address) === 0)) {\n return yield* Effect.fail(failure(\"request_failed\", \"HTTP destination has no valid addresses\", value))\n }\n if (!localhost && !addresses.every(isPublic)) yield* privateGrant\n return Object.freeze({ origin: url.origin, addresses: Object.freeze(addresses) })\n})\n\n/** Decorates the supplied client before following redirects through the guard.\n * The transport must honor manual redirects, as required by the kernel client.\n * @since 1.0.0\n * @private\n */\nexport const guarded = (\n client: HttpClient.HttpClient,\n follow = true\n): HttpClient.HttpClient.With<HttpClientError.HttpClientError, GrantStore> => {\n const checked = HttpClient.transform(\n client,\n (execute, request) =>\n authorizePreflight(\n request,\n check(request.url, client).pipe(\n Effect.mapError((cause) =>\n new HttpClientError.HttpClientError({\n reason: new HttpClientError.TransportError({ request, cause, description: cause.message })\n })\n ),\n Effect.flatMap((destination) =>\n Effect.updateContext(execute, (context: Context.Context<never>) =>\n Context.add(Context.add(context, Destination, destination), FetchHttpClient.RequestInit, {\n ...Context.getOrUndefined(context, FetchHttpClient.RequestInit),\n redirect: \"manual\"\n }))\n )\n )\n )\n )\n return follow ? HttpClient.followRedirects(checked) : checked\n}\n\n/** Recovers the typed refusal carried through Effect's HTTP error channel.\n * @since 1.0.0\n * @private\n */\nexport const refusal = (error: unknown): StdError.StdError | undefined => {\n if (!(error instanceof HttpClientError.HttpClientError) || error.reason._tag !== \"TransportError\") return undefined\n if (error.reason.cause instanceof StdError.StdError) return error.reason.cause\n if (Option.isSome(fromHttpClientError(error))) {\n return failure(\n \"permission_denied\",\n error.reason.description ?? \"HTTP permission was refused\",\n error.reason.request.url\n )\n }\n return undefined\n}\n"]}
@@ -88,6 +88,14 @@ The native CLI refuses named-container execution with `provider_unavailable`.
88
88
  An existing Docker daemon is outside its OS sandbox. Isolated providers are
89
89
  tracked in [#1790](https://github.com/smithersai/smithers/issues/1790).
90
90
 
91
+ A host sealed to one container is the exception. `SMITHERS_BASH_CONTAINER` names
92
+ the container, and `bash` and `test` then run in it through the `docker` CLI.
93
+ Every other container, and a call that names none, fails with
94
+ `outside_container`. The transport process runs outside the OS sandbox, which
95
+ denies the daemon's socket, and receives the host's `DOCKER_HOST`,
96
+ `DOCKER_CONTEXT`, `DOCKER_CONFIG`, `DOCKER_TLS_VERIFY`, and `DOCKER_CERT_PATH`,
97
+ so it reaches a rootless daemon.
98
+
91
99
  The transport always goes through a login shell, because the images an agent
92
100
  meets activate the project's interpreter from `/etc/profile.d`. A program
93
101
  spawned directly by `docker exec` gets a different Python from the one that owns
@@ -63,7 +63,7 @@ through Effect's context, so a composition adds a platform package that provides
63
63
  them:
64
64
 
65
65
  ```bash
66
- pnpm add @effect/platform-node@4.0.0-rc.115 @effect/platform-node-shared@4.0.0-rc.115
66
+ pnpm add @effect/platform-node @effect/platform-node-shared
67
67
  ```
68
68
 
69
69
  `NodeServices.layer` from `@effect/platform-node` provides `FileSystem`, `Path`,
@@ -168,6 +168,11 @@ bound, or `Container.layerNoop` was.
168
168
  **What to change.** Bind `Container.layerCommand()` for the `docker` or `podman`
169
169
  CLI, or drop the `container` field and run the command on the host.
170
170
 
171
+ The native CLI binds a transport only on a host sealed to one container: set
172
+ `SMITHERS_BASH_CONTAINER` to the container `bash` and `test` may reach. An
173
+ unsealed CLI host keeps refusing, because an existing Docker daemon is outside
174
+ its OS sandbox.
175
+
171
176
  ## provider_unavailable: no test runner is declared
172
177
 
173
178
  **What happened.** `test` ran with `TestRunner.layerNoop` bound.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@smthrs/std",
3
3
  "type": "module",
4
- "version": "1.0.0-rc.4",
4
+ "version": "1.0.0-rc.6",
5
5
  "license": "MIT",
6
6
  "smthrs": {
7
7
  "group": "agent"
@@ -401,21 +401,21 @@
401
401
  "tag": "next"
402
402
  },
403
403
  "dependencies": {
404
- "@smthrs/capability": "1.0.0-rc.4",
405
- "@smthrs/control": "1.0.0-rc.4",
406
- "@smthrs/core": "1.0.0-rc.4",
407
- "@smthrs/kernel": "1.0.0-rc.4",
408
- "@smthrs/model": "1.0.0-rc.4"
404
+ "@smthrs/capability": "1.0.0-rc.6",
405
+ "@smthrs/control": "1.0.0-rc.6",
406
+ "@smthrs/core": "1.0.0-rc.6",
407
+ "@smthrs/kernel": "1.0.0-rc.6",
408
+ "@smthrs/model": "1.0.0-rc.6"
409
409
  },
410
410
  "devDependencies": {
411
411
  "@effect/language-service": "0.87.2",
412
- "@effect/platform-node": "4.0.0-rc.115",
413
- "@effect/vitest": "4.0.0-rc.115",
412
+ "@effect/platform-node": "4.0.4",
413
+ "@effect/vitest": "4.0.4",
414
414
  "@eslint/js": "9.39.5",
415
415
  "@types/node": "26.4.1",
416
416
  "@vitest/coverage-v8": "5.0.0",
417
417
  "dprint": "0.57.1",
418
- "effect": "4.0.0-rc.115",
418
+ "effect": "4.0.4",
419
419
  "esbuild": "0.28.2",
420
420
  "eslint": "9.39.5",
421
421
  "eslint-import-resolver-typescript": "4.4.5",
@@ -428,7 +428,7 @@
428
428
  "vitest": "5.0.0"
429
429
  },
430
430
  "peerDependencies": {
431
- "effect": "4.0.0-rc.115"
431
+ "effect": "^4.0.4"
432
432
  },
433
433
  "scripts": {
434
434
  "lint": "eslint src --max-warnings=0 && dprint check",
@@ -11,7 +11,7 @@
11
11
  import * as Credential from "@smthrs/control/Credential"
12
12
  import * as HttpClient from "@smthrs/kernel/HttpClient"
13
13
  import { Clock, Effect, Layer, Redacted, Schema } from "effect"
14
- import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
14
+ import * as HttpClientRequest from "effect/http/HttpClientRequest"
15
15
  import { header, readBounded } from "./internal/Http.ts"
16
16
  import * as StdError from "./StdError.ts"
17
17
  import * as WebSearch from "./WebSearch.ts"
package/src/Fetch.ts CHANGED
@@ -5,8 +5,8 @@
5
5
  */
6
6
 
7
7
  import * as Effect from "effect/Effect"
8
+ import * as HttpClientRequest from "effect/http/HttpClientRequest"
8
9
  import * as Schema from "effect/Schema"
9
- import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
10
10
  import { capability, envelope } from "./internal/Declaration.ts"
11
11
  import { execute, Response, Timeout } from "./internal/Http.ts"
12
12
 
package/src/HttpPost.ts CHANGED
@@ -5,8 +5,8 @@
5
5
  */
6
6
 
7
7
  import * as Effect from "effect/Effect"
8
+ import * as HttpClientRequest from "effect/http/HttpClientRequest"
8
9
  import * as Schema from "effect/Schema"
9
- import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
10
10
  import { capability, envelope } from "./internal/Declaration.ts"
11
11
  import { execute, Response, Timeout } from "./internal/Http.ts"
12
12
 
@@ -12,7 +12,7 @@
12
12
  import * as ChildProcessEnvironment from "@smthrs/kernel/ChildProcessEnvironment"
13
13
  import * as ChildProcessSpawner from "@smthrs/kernel/ChildProcessSpawner"
14
14
  import { Clock, Deferred, Effect, Fiber, Layer, Option, Queue, type Scope, Semaphore, Stream } from "effect"
15
- import * as ChildProcess from "effect/unstable/process/ChildProcess"
15
+ import * as ChildProcess from "effect/process/ChildProcess"
16
16
  import { createHash } from "node:crypto"
17
17
  import * as NodeFs from "node:fs"
18
18
  import * as NodePath from "node:path"
package/src/WebFetch.ts CHANGED
@@ -12,8 +12,8 @@
12
12
  import type { GrantStore } from "@smthrs/kernel/GrantStore"
13
13
  import * as HttpClient from "@smthrs/kernel/HttpClient"
14
14
  import * as Effect from "effect/Effect"
15
+ import * as HttpClientRequest from "effect/http/HttpClientRequest"
15
16
  import * as Schema from "effect/Schema"
16
- import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
17
17
  import { capability, envelope } from "./internal/Declaration.ts"
18
18
  import { toMarkdown, toText } from "./internal/Html.ts"
19
19
  import { capOutput, header, MAX_RESPONSE_BYTES, readBounded, Timeout, withDeadline } from "./internal/Http.ts"
@@ -17,9 +17,9 @@
17
17
  import * as ChildProcessEnvironment from "@smthrs/kernel/ChildProcessEnvironment"
18
18
  import * as ChildProcessSpawner from "@smthrs/kernel/ChildProcessSpawner"
19
19
  import * as Effect from "effect/Effect"
20
+ import * as ChildProcess from "effect/process/ChildProcess"
20
21
  import * as Schema from "effect/Schema"
21
22
  import * as Stream from "effect/Stream"
22
- import * as ChildProcess from "effect/unstable/process/ChildProcess"
23
23
  import * as StdError from "../StdError.ts"
24
24
 
25
25
  /**
@@ -7,9 +7,9 @@
7
7
  import type { GrantStore } from "@smthrs/kernel/GrantStore"
8
8
  import * as HttpClient from "@smthrs/kernel/HttpClient"
9
9
  import * as Effect from "effect/Effect"
10
+ import * as HttpClientRequest from "effect/http/HttpClientRequest"
10
11
  import * as Schema from "effect/Schema"
11
12
  import * as Stream from "effect/Stream"
12
- import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
13
13
  import * as StdError from "../StdError.ts"
14
14
  import { guarded, refusal } from "./HttpNetwork.ts"
15
15
  import { MAX_OUTPUT_BYTES, notice, truncateBytes } from "./Text.ts"
@@ -13,9 +13,9 @@ import {
13
13
  supportsDestinationPinning
14
14
  } from "@smthrs/kernel/HttpClient"
15
15
  import { Context, Effect, Option } from "effect"
16
- import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient"
17
- import * as HttpClient from "effect/unstable/http/HttpClient"
18
- import * as HttpClientError from "effect/unstable/http/HttpClientError"
16
+ import * as FetchHttpClient from "effect/http/FetchHttpClient"
17
+ import * as HttpClient from "effect/http/HttpClient"
18
+ import * as HttpClientError from "effect/http/HttpClientError"
19
19
  import { lookup } from "node:dns/promises"
20
20
  import { BlockList, isIP } from "node:net"
21
21
  import * as StdError from "../StdError.ts"