Skip to content

Migrate fjs/dev/update to .f.mjs - #1491

Merged
sergey-shandar merged 8 commits into
mainfrom
claude/convert-f-ts-to-f-mjs-12
Aug 11, 2026
Merged

Migrate fjs/dev/update to .f.mjs#1491
sergey-shandar merged 8 commits into
mainfrom
claude/convert-f-ts-to-f-mjs-12

Conversation

@sergey-shandar

Copy link
Copy Markdown
Contributor

Summary

  • Migrates fjs/dev/update/module.f.ts from authored TypeScript to JSDoc-typed .f.mjs, per todo/migrate-typescript-to-mjs.md.
  • No local types to split — it reuses Mkdir/NodeProgram/ReadFile/WriteFile from effects/node/types.ts and Effect from effects/types.ts, so no types.ts companion is needed.
  • proof.f.ts stays TypeScript for now — it has a runtime dependency on effects/node/virtual/module.f.ts, still unmigrated.
  • A dependency leaf: nothing else in the repo imports dev/update.

Test plan

  • npx tsc --noEmit clean
  • node ./fjs/module.ts t — 2357/2357 pass

Generated by Claude Code

claude added 2 commits August 11, 2026 15:49
Leaf module with no local types to split — reuses Mkdir/NodeProgram/
ReadFile/WriteFile/Effect from effects/node and effects. proof.f.ts
stays TypeScript: it has a runtime dependency on
effects/node/virtual/module.f.ts, still unmigrated.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
functionalscript fac21a6 Commit Preview URL

Branch Preview URL
Aug 11 2026, 04:53 PM

claude added 2 commits August 11, 2026 15:54
Leaf module with no local types and no dependents. proof.f.ts stays
TypeScript: it has a runtime dependency on
effects/node/virtual/module.f.ts, still unmigrated. Updates the stale
line-number citation in effects' map-step-combinator todo doc.
dev-update and index-html hardcoded ./fjs/dev/update/module.f.ts and
./fjs/website/module.f.ts, both migrated to .f.mjs earlier in this
PR. This broke the Cloudflare Workers Build, which runs index-html to
generate the deployed site. Verified both scripts run clean and
produce unchanged output.

@o2alexanderfedin o2alexanderfedin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. Reviewed at a0bab54 against main (dff17b0). Two modules — fjs/dev/update and fjs/website. CI green, nothing to flag.

The package.json fix is the interesting part

dev-update and index-html pointed at module.f.ts paths this PR renames. That is a class neither tsc nor the test suite can catch — the scripts are only exercised when someone runs them — so it would have sat broken until it bit somebody. Both run now:

$ npm run dev-update   → OK
$ npm run index-html   → OK

I swept the rest for the same shape and found none remaining: every .f.ts/.f.mjs path in package.json and the other config files resolves, and .github has no such references at all.

Everything else

  • npx tsc clean; 2357 pass / 0 fail, matching main.
  • Both modules are token-identical to main's compiled output.
  • Public API completely untouched — 0 removed / 0 added / 0 changed for exported type aliases and exported const signatures. That is what a leaf migration with no local types should look like, and it matches the summary's claim that no types.ts companion was needed.
  • No any as a type in any emitted declaration.
  • Links 144/144, none added, 0 label/target mismatches, and no stale .f.ts references to either migrated module outside the CHANGELOG entries themselves.
  • CHANGELOG covers both.

The proof.f.ts rationale is accurate this time, which I checked rather than assumed given it went stale on #1488: both proofs import virtual and emptyState from effects/node/virtual/module.f.ts, and that module is still TypeScript on disk. So §2 genuinely blocks proof.f.mjs for both, and the summary says so correctly.

proof.f.ts stays TypeScript for now: it has a runtime dependency on
effects/node/virtual/module.f.ts, still unmigrated. Updates the
cas/cli and top-level module.f.ts dependents, plus stale module.f.ts
doc references (including line-number citations) across README.md and
five todo docs.
@sergey-shandar

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4770078e7d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread fjs/cli/types.ts Outdated
import type { Effect } from '../effects/types.ts'

/** @internal */
export type _Handler<O extends NodeOp> = (options: NodeProgramOptions) => Effect<O, number>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep _Handler private

This migration changes the previously module-private Handler alias into an exported _Handler; because stripInternal is disabled, the generated types.d.ts retains that export and package consumers can import it despite the @internal tag. That unnecessarily expands the public API and creates a compatibility obligation for an implementation detail. Keep the alias non-exported, as it was before the migration. The repository requires migrations to preserve public assignability and declaration-emission behavior.

AGENTS.md reference: AGENTS.md:L449-L454

Useful? React with 👍 / 👎.

types.ts is real TypeScript, not JSDoc-constrained, so a non-exported
type can be referenced by an exported type in the same file without
issue — the underscore-export convention only applies where a JSDoc
@typedef forces the export. Handler was never imported from
module.f.mjs, so exporting it needlessly widened the declared surface.
@sergey-shandar

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3098a083d3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread fjs/cli/module.f.mjs
*
* @module
*/
import { errorExit, log } from '../effects/node/module.f.mjs'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add a blank line after each module header

When declaration files are emitted, placing the first import immediately after the closing @module block causes TypeScript to drop the module documentation from the generated .d.mts. The same adjacency occurs in fjs/dev/update/module.f.mjs:6 and fjs/website/module.f.mjs:6, so all three newly migrated modules lose their module-level documentation in the published declarations; insert a blank line after each header.

Useful? React with 👍 / 👎.

Comment thread fjs/README.md Outdated
fjs/module.ts — Node.js entry point (runs main via the node runner)
fjs/module.f.ts — FunctionalScript command dispatcher (Commands list + dispatch)
fjs/cli/module.f.ts — generic Command/Commands/dispatch primitives
fjs/cli/module.f.mjs — generic Command/Commands/dispatch primitives

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the remaining CLI documentation link

This rename updates the architecture reference, but fjs/cas/README.md:13 still links to cli/module.f.ts, which no longer exists after this change. Readers following the documented CAS CLI link therefore land on a missing file; update it to cli/module.f.mjs as part of the rename.

Useful? React with 👍 / 👎.

Without it, TypeScript's declaration emit drops the module doc
comment entirely from the generated .d.mts — verified against the
actual emitted output before and after.

Copy link
Copy Markdown
Contributor Author

Checked both findings.

@module blank-line issue — confirmed and fixed (d791a69). Verified via the actual declaration emit (npx tsc --noEmit false --declaration --emitDeclarationOnly --outDir <scratch>): before the fix, fjs/cli/module.f.d.mts started directly with the import statements and the module doc comment was gone entirely; after adding a blank line following @module in all three files (cli, dev/update, website), the doc comment is emitted correctly in all three.

fjs/cas/README.md:13 link — false positive. That link, [\cas` CLI](cli/module.f.ts), is relative to fjs/cas/README.md, so it resolves to fjs/cas/cli/module.f.ts— a different, still-unmigrated module (this PR only touched the top-levelfjs/cli`). That file still exists at that path, so the link is unaffected by this PR.


Generated by Claude Code

@sergey-shandar

Copy link
Copy Markdown
Contributor Author

@codex review

@o2alexanderfedin o2alexanderfedin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-approving at d791a69. fjs/cli joins, and the two follow-up commits are both pre-empting things that came up earlier in this migration rather than waiting for review to raise them.

Handler stays private — and this is the better fix

3098a08 keeps Handler non-exported in fjs/cli/types.ts. Verified against main: it emits as a bare type Handler<O extends NodeOp> = … on both sides, no export, so the privacy is exactly preserved.

Worth naming why this is cleaner than the _Byte/_NodeList/_Type0 outcomes earlier: those types had to move into JSDoc @typedefs, which have no non-exported form, so the _ prefix was the only marker available. Handler moved into a types.ts — real TypeScript — where a plain non-exported type is expressible. Reaching for the stronger option when the file format allows it is the right instinct.

The @module blank lines are load-bearing

d791a69 adds a blank line after the @module block in fjs/cli/types.ts, fjs/dev/update/module.f.mjs, and fjs/website/module.f.mjs. All three have an import as the next statement, which is precisely the shape where TypeScript folds the header into the import's leading comment and drops it on elision. I confirmed the header survives emit in all three (types.js for cli, the .d.mts for the other two). Fixing that at authoring time rather than discovering it in a later sweep is the outcome I was hoping for after the 18-file case.

Everything re-verified at this head

  • npx tsc clean; 2357 pass / 0 fail, matching main.
  • All three modules token-identical to main's compiled output.
  • Public API untouched: 0 removed / 0 added / 0 changed, on both exported type aliases and exported const signatures.
  • No any as a type in any emitted declaration.
  • Links 144/144, none added, 0 label/target mismatches.
  • Every .f.ts/.f.mjs path in package.json still resolves — including fjs/cli's arrival not stranding one.
  • CHANGELOG covers all three.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d791a69e1f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread fjs/cli/todo/options-edsl.md Outdated
### Problem

`Command` (`fjs/cli/module.f.ts`) hands every handler a raw
`Command` (`fjs/cli/module.f.mjs`) hands every handler a raw

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Point CLI type references to types.ts

After this migration, Command and Commands are exported only from fjs/cli/types.ts, but this updated reference—and the corresponding ownership claims in dispatch-help-rendering.md, positional-arity-check.md, fjs/todo/66g-fjs-run-commands.md, and fjs/README.md—still directs readers to module.f.mjs. Anyone implementing these issue designs would look for or import types from a runtime module that does not export them; update type-level references to types.ts while retaining module.f.mjs references for dispatch and runtime combinators.

AGENTS.md reference: AGENTS.md:L449-L454

Useful? React with 👍 / 👎.

Command and Commands are exported only from types.ts after the
migration; dispatch stays correctly cited in module.f.mjs. Also
refreshes dispatch's stale line-number citations (:18-49 -> :18-50).
@sergey-shandar

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: fac21a6c16

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@sergey-shandar
sergey-shandar added this pull request to the merge queue Aug 11, 2026
Merged via the queue into main with commit caa5894 Aug 11, 2026
19 checks passed
@sergey-shandar
sergey-shandar deleted the claude/convert-f-ts-to-f-mjs-12 branch August 11, 2026 17:01
sergey-shandar pushed a commit that referenced this pull request Aug 11, 2026
#1491 migrated fjs/dev/update — the module this one is modelled on — so the
writer's whole runtime closure is now .f.mjs and nothing blocks it. Shipping a
new authored .f.ts implementation would work against the stage-1 migration.

The proof stays .f.ts: it needs `virtual` from effects/node/virtual, which is
still TypeScript. Same split fjs/dev/update has.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FyMg2KPgfJeQ5FXGXjyFmd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants