magik 0.0.1

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.
data/lib/magik/pwa.rb ADDED
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magik
4
+ # Installable progressive web app metadata. Explicitly no offline caching: the server
5
+ # is the single source of truth.
6
+ #
7
+ # Implements: **Phase 8 — i18n, PWA, Notifications** of `docs/idea/00-build-spec.md`.
8
+ #
9
+ # Planned DSL surface, copied from the spec:
10
+ #
11
+ # * `pwa do name/icon/display end`
12
+ #
13
+ # Status: **Not implemented — spec only.** Every entry point below raises
14
+ # {NotImplementedError}. Nothing here reads config, touches a database or
15
+ # emits a byte of HTML.
16
+ #
17
+ # @see Magik::SUBSYSTEMS
18
+ module PWA
19
+ # The build-spec phase this subsystem implements.
20
+ # @return [String]
21
+ SPEC_PHASE = "Phase 8 — i18n, PWA, Notifications"
22
+
23
+ # The DSL this subsystem will expose, verbatim from the spec.
24
+ # @return [Array<String>]
25
+ DSL_SURFACE = [
26
+ "pwa do name/icon/display end"
27
+ ].freeze
28
+
29
+ # Implementation status of this subsystem.
30
+ # @return [String]
31
+ STATUS = "Not implemented — spec only"
32
+
33
+ # Entry point for the PWA DSL.
34
+ #
35
+ # @param _args [Array] ignored
36
+ # @param _options [Hash] ignored
37
+ # @return [void] never returns
38
+ # @raise [NotImplementedError] always, until Phase 8 lands
39
+ def self.define(*_args, **_options)
40
+ raise NotImplementedError, "Magik::PWA is spec-only; see docs/idea/00-build-spec.md"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magik
4
+ # Opt-in realtime. Default is plain request/response; nothing costs anything until a
5
+ # screen declares `live` or a `channel` exists.
6
+ #
7
+ # Implements: **Phase 3 — Realtime (opt-in)** of `docs/idea/00-build-spec.md`.
8
+ #
9
+ # Planned DSL surface, copied from the spec:
10
+ #
11
+ # * `live :state_var, on: "channel:name"`
12
+ # * `channel :name do subscribe_to/on_create/on_update end`
13
+ # * `broadcast "channel", :event, payload`
14
+ # * `presence for online/cursor tracking`
15
+ # * `backend: Postgres LISTEN/NOTIFY (default) → Redis pub/sub (swap via config)`
16
+ #
17
+ # Status: **Not implemented — spec only.** Every entry point below raises
18
+ # {NotImplementedError}. Nothing here reads config, touches a database or
19
+ # emits a byte of HTML.
20
+ #
21
+ # @see Magik::SUBSYSTEMS
22
+ module Realtime
23
+ # The build-spec phase this subsystem implements.
24
+ # @return [String]
25
+ SPEC_PHASE = "Phase 3 — Realtime (opt-in)"
26
+
27
+ # The DSL this subsystem will expose, verbatim from the spec.
28
+ # @return [Array<String>]
29
+ DSL_SURFACE = [
30
+ "live :state_var, on: \"channel:name\"",
31
+ "channel :name do subscribe_to/on_create/on_update end",
32
+ "broadcast \"channel\", :event, payload",
33
+ "presence for online/cursor tracking",
34
+ "backend: Postgres LISTEN/NOTIFY (default) → Redis pub/sub (swap via config)"
35
+ ].freeze
36
+
37
+ # Implementation status of this subsystem.
38
+ # @return [String]
39
+ STATUS = "Not implemented — spec only"
40
+
41
+ # Entry point for the Realtime DSL.
42
+ #
43
+ # @param _args [Array] ignored
44
+ # @param _options [Hash] ignored
45
+ # @return [void] never returns
46
+ # @raise [NotImplementedError] always, until Phase 3 lands
47
+ def self.define(*_args, **_options)
48
+ raise NotImplementedError, "Magik::Realtime is spec-only; see docs/idea/00-build-spec.md"
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magik
4
+ # The UI DSL. Compiles components and screens to server-rendered HTML plus htmx
5
+ # attributes. There is no SPA framework and there never will be.
6
+ #
7
+ # Implements: **Phase 2 — Rendering & Actions** of `docs/idea/00-build-spec.md`.
8
+ #
9
+ # Planned DSL surface, copied from the spec:
10
+ #
11
+ # * `component :Name do prop; body do ... end end`
12
+ # * `screen :Name do state/body end`
13
+ # * `kit: button, form, field, data_table, modal, toast, card, list, grid, tabs, stat, chart`
14
+ # * `theme system: design tokens, light/dark mode via CSS vars`
15
+ #
16
+ # Status: **Not implemented — spec only.** Every entry point below raises
17
+ # {NotImplementedError}. Nothing here reads config, touches a database or
18
+ # emits a byte of HTML.
19
+ #
20
+ # @see Magik::SUBSYSTEMS
21
+ module Render
22
+ # The build-spec phase this subsystem implements.
23
+ # @return [String]
24
+ SPEC_PHASE = "Phase 2 — Rendering & Actions"
25
+
26
+ # The DSL this subsystem will expose, verbatim from the spec.
27
+ # @return [Array<String>]
28
+ DSL_SURFACE = [
29
+ "component :Name do prop; body do ... end end",
30
+ "screen :Name do state/body end",
31
+ "kit: button, form, field, data_table, modal, toast, card, list, grid, tabs, stat, chart",
32
+ "theme system: design tokens, light/dark mode via CSS vars"
33
+ ].freeze
34
+
35
+ # Implementation status of this subsystem.
36
+ # @return [String]
37
+ STATUS = "Not implemented — spec only"
38
+
39
+ # Entry point for the Render DSL.
40
+ #
41
+ # @param _args [Array] ignored
42
+ # @param _options [Hash] ignored
43
+ # @return [void] never returns
44
+ # @raise [NotImplementedError] always, until Phase 2 lands
45
+ def self.define(*_args, **_options)
46
+ raise NotImplementedError, "Magik::Render is spec-only; see docs/idea/00-build-spec.md"
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magik
4
+ # Convention-driven routing: an action name becomes a path, a screen auto-routes. Also
5
+ # the dev server and hot reload entry point.
6
+ #
7
+ # Implements: **Phase 2 — Rendering & Actions (build order step 4)** of `docs/idea/00-build-spec.md`.
8
+ #
9
+ # Planned DSL surface, copied from the spec:
10
+ #
11
+ # * `convention: action name → path`
12
+ # * `screens are auto-routed by name`
13
+ #
14
+ # Status: **Not implemented — spec only.** Every entry point below raises
15
+ # {NotImplementedError}. Nothing here reads config, touches a database or
16
+ # emits a byte of HTML.
17
+ #
18
+ # @see Magik::SUBSYSTEMS
19
+ module Router
20
+ # The build-spec phase this subsystem implements.
21
+ # @return [String]
22
+ SPEC_PHASE = "Phase 2 — Rendering & Actions (build order step 4)"
23
+
24
+ # The DSL this subsystem will expose, verbatim from the spec.
25
+ # @return [Array<String>]
26
+ DSL_SURFACE = [
27
+ "convention: action name → path",
28
+ "screens are auto-routed by name"
29
+ ].freeze
30
+
31
+ # Implementation status of this subsystem.
32
+ # @return [String]
33
+ STATUS = "Not implemented — spec only"
34
+
35
+ # Entry point for the Router DSL.
36
+ #
37
+ # @param _args [Array] ignored
38
+ # @param _options [Hash] ignored
39
+ # @return [void] never returns
40
+ # @raise [NotImplementedError] always, until Phase 2 lands
41
+ def self.define(*_args, **_options)
42
+ raise NotImplementedError, "Magik::Router is spec-only; see docs/idea/00-build-spec.md"
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magik
4
+ # The migration DSL over Sequel migrations.
5
+ #
6
+ # Implements: **Phase 1 — Foundation** of `docs/idea/00-build-spec.md`.
7
+ #
8
+ # Planned DSL surface, copied from the spec:
9
+ #
10
+ # * `migrate :Name do up/down end`
11
+ #
12
+ # Status: **Not implemented — spec only.** Every entry point below raises
13
+ # {NotImplementedError}. Nothing here reads config, touches a database or
14
+ # emits a byte of HTML.
15
+ #
16
+ # @see Magik::SUBSYSTEMS
17
+ module Schema
18
+ # The build-spec phase this subsystem implements.
19
+ # @return [String]
20
+ SPEC_PHASE = "Phase 1 — Foundation"
21
+
22
+ # The DSL this subsystem will expose, verbatim from the spec.
23
+ # @return [Array<String>]
24
+ DSL_SURFACE = [
25
+ "migrate :Name do up/down end"
26
+ ].freeze
27
+
28
+ # Implementation status of this subsystem.
29
+ # @return [String]
30
+ STATUS = "Not implemented — spec only"
31
+
32
+ # Entry point for the Schema DSL.
33
+ #
34
+ # @param _args [Array] ignored
35
+ # @param _options [Hash] ignored
36
+ # @return [void] never returns
37
+ # @raise [NotImplementedError] always, until Phase 1 lands
38
+ def self.define(*_args, **_options)
39
+ raise NotImplementedError, "Magik::Schema is spec-only; see docs/idea/00-build-spec.md"
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magik
4
+ # The test DSL, compiling to Minitest (never RSpec), with auto-inferred factories and
5
+ # a parallel runner.
6
+ #
7
+ # Implements: **Phase 9 — Testing** of `docs/idea/00-build-spec.md`.
8
+ #
9
+ # Planned DSL surface, copied from the spec:
10
+ #
11
+ # * `test :Name do it "..." do expect(...) end end`
12
+ # * `helpers: perform_action, render_screen, concurrently(n), travel_to`
13
+ # * `helpers: assert_enqueued, assert_broadcast, assert_notified`
14
+ # * `parallel: one Ractor per test file group, workers: :auto, transactional rollback per test`
15
+ # * `magik test, magik test --watch, magik test --changed`
16
+ #
17
+ # Status: **Not implemented — spec only.** Every entry point below raises
18
+ # {NotImplementedError}. Nothing here reads config, touches a database or
19
+ # emits a byte of HTML.
20
+ #
21
+ # @see Magik::SUBSYSTEMS
22
+ module Testing
23
+ # The build-spec phase this subsystem implements.
24
+ # @return [String]
25
+ SPEC_PHASE = "Phase 9 — Testing"
26
+
27
+ # The DSL this subsystem will expose, verbatim from the spec.
28
+ # @return [Array<String>]
29
+ DSL_SURFACE = [
30
+ "test :Name do it \"...\" do expect(...) end end",
31
+ "helpers: perform_action, render_screen, concurrently(n), travel_to",
32
+ "helpers: assert_enqueued, assert_broadcast, assert_notified",
33
+ "parallel: one Ractor per test file group, workers: :auto, transactional rollback per test",
34
+ "magik test, magik test --watch, magik test --changed"
35
+ ].freeze
36
+
37
+ # Implementation status of this subsystem.
38
+ # @return [String]
39
+ STATUS = "Not implemented — spec only"
40
+
41
+ # Entry point for the Testing DSL.
42
+ #
43
+ # @param _args [Array] ignored
44
+ # @param _options [Hash] ignored
45
+ # @return [void] never returns
46
+ # @raise [NotImplementedError] always, until Phase 9 lands
47
+ def self.define(*_args, **_options)
48
+ raise NotImplementedError, "Magik::Testing is spec-only; see docs/idea/00-build-spec.md"
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magik
4
+ # The released version of the `magik` gem.
5
+ #
6
+ # `0.0.1` is a **name-reservation release**: the gem name is claimed on
7
+ # RubyGems, the public surface is a CLI shim plus documented, spec-only
8
+ # subsystem stubs. No framework behaviour from `docs/idea/00-build-spec.md`
9
+ # is implemented.
10
+ #
11
+ # The value follows [Semantic Versioning](https://semver.org). While the
12
+ # major version is `0`, minor bumps may break the public API.
13
+ #
14
+ # @return [String] a frozen `MAJOR.MINOR.PATCH` string
15
+ # @example Read the version at runtime
16
+ # require "magik"
17
+ # Magik::VERSION # => "0.0.1"
18
+ VERSION = "0.0.1"
19
+ end
data/lib/magik.rb ADDED
@@ -0,0 +1,258 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+
5
+ require_relative "magik/version"
6
+
7
+ # Magik is an opinionated, full-stack Ruby framework targeting TruffleRuby:
8
+ # one DSL for models, screens, actions, realtime channels, background jobs,
9
+ # ledgers, APIs and admin panels, rendered server-side as HTML + htmx.
10
+ #
11
+ # **Status as of 2026-08-26: spec only.** The product specification lives in
12
+ # `docs/idea/00-build-spec.md` and is entirely unimplemented. What ships in
13
+ # this gem today is:
14
+ #
15
+ # * {Magik::VERSION} — the name-reservation version string.
16
+ # * {Magik::Error} — the stable `MAGIK_*` error-code convention.
17
+ # * {Magik::CLI} — a working `magik version` / `magik help` command line.
18
+ # * One documented, spec-only stub module per planned subsystem
19
+ # (see {Magik::SUBSYSTEMS}); every entry point raises {NotImplementedError}.
20
+ #
21
+ # Nothing in this gem renders a page, talks to a database, or runs a job.
22
+ #
23
+ # @see https://github.com/developerz-ai/magik
24
+ module Magik
25
+ # Every planned subsystem, mapped from its file basename under `lib/magik/`
26
+ # to the constant it defines. Each entry mirrors one area of the build spec.
27
+ #
28
+ # The map drives {https://ruby-doc.org/core/Module.html#method-i-autoload
29
+ # autoload} registration below, so requiring `magik` is cheap: a subsystem
30
+ # file is only read when its constant is first referenced.
31
+ #
32
+ # @return [Hash{Symbol => Symbol}] file basename => constant name
33
+ # @example List the planned subsystems
34
+ # Magik::SUBSYSTEMS.keys # => [:core, :cli, :model, ...]
35
+ SUBSYSTEMS = {
36
+ core: :Core,
37
+ cli: :CLI,
38
+ model: :Model,
39
+ schema: :Schema,
40
+ render: :Render,
41
+ action: :Action,
42
+ router: :Router,
43
+ realtime: :Realtime,
44
+ jobs: :Jobs,
45
+ ledger: :Ledger,
46
+ api: :API,
47
+ auth: :Auth,
48
+ billing: :Billing,
49
+ admin: :Admin,
50
+ i18n: :I18n,
51
+ pwa: :PWA,
52
+ notify: :Notify,
53
+ testing: :Testing,
54
+ domains: :Domains,
55
+ check: :Check
56
+ }.freeze
57
+
58
+ # The subsystems that are documentation-only: their modules load and carry
59
+ # their spec metadata, but every entry point raises {NotImplementedError}.
60
+ #
61
+ # {Magik::CLI} is deliberately absent — it is the one subsystem with real,
62
+ # useful behaviour today.
63
+ #
64
+ # @return [Array<Symbol>] file basenames, a subset of {SUBSYSTEMS} keys
65
+ SPEC_ONLY_SUBSYSTEMS = (SUBSYSTEMS.keys - [:cli]).freeze
66
+
67
+ SUBSYSTEMS.each { |file, const| autoload const, "magik/#{file}" }
68
+
69
+ # Base class for every error Magik raises.
70
+ #
71
+ # Magik errors are not free-form strings. Each one carries three things, and
72
+ # all three are required:
73
+ #
74
+ # 1. a **stable code** matching {CODE_FORMAT} (`MAGIK_SOMETHING`) that is
75
+ # safe to grep for, link to, and match on in tests and CI;
76
+ # 2. a **cause** — one sentence saying what actually went wrong;
77
+ # 3. a **fix** — a runnable command or a concrete edit, never "check your
78
+ # configuration".
79
+ #
80
+ # The rendered message is deterministic:
81
+ #
82
+ # ```text
83
+ # MAGIK_LEDGER_UNBALANCED: entries for :Payouts do not balance (debits 1200, credits 900).
84
+ # fix: run `magik check --ledger Payouts`
85
+ # ```
86
+ #
87
+ # Subclasses declare their defaults with the {code} and {fix} class-level
88
+ # DSL, so a raise site only has to supply the cause.
89
+ #
90
+ # @example Raise a one-off error
91
+ # raise Magik::Error.new(
92
+ # "the app has no `App.define` block",
93
+ # code: "MAGIK_NO_APP",
94
+ # fix: "run `magik new myapp` to generate one"
95
+ # )
96
+ # @example Declare a reusable error class
97
+ # class MissingTenant < Magik::Error
98
+ # code "MAGIK_MISSING_TENANT"
99
+ # fix "add `tenant_by :subdomain` to your App.define block"
100
+ # end
101
+ # raise MissingTenant, "query on :Invoice has no tenant_id in WHERE"
102
+ class Error < StandardError
103
+ # The shape every Magik error code must take: `MAGIK_` followed by
104
+ # underscore-separated uppercase words.
105
+ #
106
+ # @return [Regexp]
107
+ CODE_FORMAT = /\AMAGIK_[A-Z0-9]+(?:_[A-Z0-9]+)*\z/
108
+
109
+ # Fallback code for {Magik::Error} itself.
110
+ # @return [String]
111
+ DEFAULT_CODE = "MAGIK_ERROR"
112
+
113
+ # Fallback fix for {Magik::Error} itself.
114
+ # @return [String]
115
+ DEFAULT_FIX = "read the raised cause above, then see docs/idea/00-build-spec.md"
116
+
117
+ class << self
118
+ # Get or set the default error code for this class and its subclasses.
119
+ #
120
+ # Called with an argument it is a writer; called without, a reader that
121
+ # walks up the superclass chain.
122
+ #
123
+ # @param value [String, nil] a code matching {CODE_FORMAT}, or nil to read
124
+ # @return [String] the effective code for this class
125
+ # @raise [ArgumentError] if `value` does not match {CODE_FORMAT}
126
+ def code(value = nil)
127
+ return @code = Error.validate_code!(value) unless value.nil?
128
+
129
+ @code || (superclass.respond_to?(:code) ? superclass.code : DEFAULT_CODE)
130
+ end
131
+
132
+ # Get or set the default fix line for this class and its subclasses.
133
+ #
134
+ # @param value [String, nil] an actionable fix, or nil to read
135
+ # @return [String] the effective fix for this class
136
+ # @raise [ArgumentError] if `value` is blank
137
+ def fix(value = nil)
138
+ return @fix = Error.validate_fix!(value) unless value.nil?
139
+
140
+ @fix || (superclass.respond_to?(:fix) ? superclass.fix : DEFAULT_FIX)
141
+ end
142
+
143
+ # @api private
144
+ # @param value [String] candidate error code
145
+ # @return [String] the frozen, validated code
146
+ # @raise [ArgumentError] if the code is malformed
147
+ def validate_code!(value)
148
+ string = value.to_s
149
+ return string.freeze if CODE_FORMAT.match?(string)
150
+
151
+ raise ArgumentError, "error code #{string.inspect} must match #{CODE_FORMAT.source}"
152
+ end
153
+
154
+ # @api private
155
+ # @param value [String, nil] candidate cause text
156
+ # @param klass [Class] the error class, used as the fallback cause
157
+ # @return [String] a frozen, non-empty cause
158
+ def normalize_cause(value, klass)
159
+ string = value.to_s
160
+ (string.strip.empty? ? klass.name.to_s : string).freeze
161
+ end
162
+
163
+ # @api private
164
+ # @param value [String] candidate fix line
165
+ # @return [String] the frozen, validated fix
166
+ # @raise [ArgumentError] if the fix is blank
167
+ def validate_fix!(value)
168
+ string = value.to_s
169
+ return string.freeze unless string.strip.empty?
170
+
171
+ raise ArgumentError, "a Magik error needs a non-empty fix: line"
172
+ end
173
+ end
174
+
175
+ # The stable, greppable error code.
176
+ # @return [String] e.g. `"MAGIK_UNKNOWN_COMMAND"`
177
+ attr_reader :code
178
+
179
+ # What went wrong, in one sentence.
180
+ #
181
+ # Named `cause_text` because `Exception#cause` is reserved by Ruby for the
182
+ # exception that was in flight when this one was raised.
183
+ #
184
+ # @return [String]
185
+ attr_reader :cause_text
186
+
187
+ # How to make it stop — a runnable command or a concrete edit.
188
+ # @return [String]
189
+ attr_reader :fix
190
+
191
+ # @param cause_text [String] what went wrong, one sentence
192
+ # @param code [String] a code matching {CODE_FORMAT}; defaults to the
193
+ # class-level {Error.code}
194
+ # @param fix [String] an actionable fix; defaults to the class-level
195
+ # {Error.fix}
196
+ # @raise [ArgumentError] if the code is malformed or the fix is blank
197
+ def initialize(cause_text = nil, code: self.class.code, fix: self.class.fix)
198
+ @code = Error.validate_code!(code)
199
+ @cause_text = Error.normalize_cause(cause_text, self.class)
200
+ @fix = Error.validate_fix!(fix)
201
+ super(self.class.render(@code, @cause_text, @fix))
202
+ end
203
+
204
+ # Render the canonical two-line message for an error triple.
205
+ #
206
+ # @param code [String] the error code
207
+ # @param cause_text [String] what went wrong
208
+ # @param fix [String] how to fix it
209
+ # @return [String] `"CODE: cause\n fix: fix"`
210
+ def self.render(code, cause_text, fix)
211
+ "#{code}: #{cause_text}\n fix: #{fix}"
212
+ end
213
+
214
+ # The error as plain data, ready for `--json` output or a log line.
215
+ #
216
+ # @return [Hash{Symbol => String}] with keys `:code`, `:cause`, `:fix`
217
+ def to_h
218
+ { code: code, cause: cause_text, fix: fix }
219
+ end
220
+ end
221
+
222
+ # Raised when a CLI command is named in the spec but not implemented yet.
223
+ #
224
+ # @see Magik::CLI
225
+ class CommandNotImplementedError < Error
226
+ code "MAGIK_COMMAND_NOT_IMPLEMENTED"
227
+ fix "run `magik help` for the commands that work today; " \
228
+ "track the rest in docs/idea/00-build-spec.md"
229
+ end
230
+
231
+ # Raised when a CLI command is not a Magik command at all.
232
+ #
233
+ # @see Magik::CLI
234
+ class UnknownCommandError < Error
235
+ code "MAGIK_UNKNOWN_COMMAND"
236
+ fix "run `magik help` to list every command"
237
+ end
238
+
239
+ # Raised when the command line carries a flag Magik does not understand.
240
+ #
241
+ # @see Magik::CLI
242
+ class InvalidOptionError < Error
243
+ code "MAGIK_INVALID_OPTION"
244
+ fix "run `magik help` to list the supported options"
245
+ end
246
+
247
+ # The installed gem's root directory — the parent of `lib/`.
248
+ #
249
+ # Useful for locating packaged assets and the specification itself, e.g.
250
+ # `Magik.root.join("docs/idea/00-build-spec.md")`.
251
+ #
252
+ # @return [Pathname] an absolute, resolved path
253
+ # @example
254
+ # Magik.root.join("lib", "magik.rb").exist? # => true
255
+ def self.root
256
+ @root ||= Pathname.new(File.expand_path("..", __dir__))
257
+ end
258
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: magik
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - developerz.ai
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2026-08-26 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: |
14
+ Magik is a full-stack Ruby framework designed for TruffleRuby: one DSL for models,
15
+ screens, actions, realtime channels, background jobs, ledgers, APIs and admin panels.
16
+ The server renders HTML and htmx handles interactivity — there is no separate frontend
17
+ framework, no offline mode, and no heavy client-side compute.
18
+
19
+ Status as of 2026-08-26: this is a name-reservation release. The specification lives in
20
+ docs/idea/00-build-spec.md and is entirely unimplemented. What ships today is the gem
21
+ skeleton, the MAGIK_* error-code convention, a `magik version` / `magik help` CLI, and
22
+ one documented, spec-only stub module per planned subsystem. Nothing renders a page,
23
+ connects to a database, or runs a job yet.
24
+ email:
25
+ - admin@developerz.ai
26
+ executables:
27
+ - magik
28
+ extensions: []
29
+ extra_rdoc_files: []
30
+ files:
31
+ - CHANGELOG.md
32
+ - LICENSE
33
+ - README.md
34
+ - exe/magik
35
+ - lib/magik.rb
36
+ - lib/magik/action.rb
37
+ - lib/magik/admin.rb
38
+ - lib/magik/api.rb
39
+ - lib/magik/auth.rb
40
+ - lib/magik/billing.rb
41
+ - lib/magik/check.rb
42
+ - lib/magik/cli.rb
43
+ - lib/magik/core.rb
44
+ - lib/magik/domains.rb
45
+ - lib/magik/i18n.rb
46
+ - lib/magik/jobs.rb
47
+ - lib/magik/ledger.rb
48
+ - lib/magik/model.rb
49
+ - lib/magik/notify.rb
50
+ - lib/magik/pwa.rb
51
+ - lib/magik/realtime.rb
52
+ - lib/magik/render.rb
53
+ - lib/magik/router.rb
54
+ - lib/magik/schema.rb
55
+ - lib/magik/testing.rb
56
+ - lib/magik/version.rb
57
+ homepage: https://github.com/developerz-ai/magik
58
+ licenses:
59
+ - MIT
60
+ metadata:
61
+ homepage_uri: https://github.com/developerz-ai/magik
62
+ source_code_uri: https://github.com/developerz-ai/magik
63
+ changelog_uri: https://github.com/developerz-ai/magik/blob/main/CHANGELOG.md
64
+ documentation_uri: https://developerz-ai.github.io/magik/api/
65
+ bug_tracker_uri: https://github.com/developerz-ai/magik/issues
66
+ rubygems_mfa_required: 'true'
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '3.2'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubygems_version: 3.4.20
83
+ signing_key:
84
+ specification_version: 4
85
+ summary: An opinionated, full-stack Ruby framework for TruffleRuby — one DSL for the
86
+ whole app.
87
+ test_files: []