create-majlis 0.6.2 → 0.7.0

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 (2) hide show
  1. package/dist/index.js +33 -962
  2. package/package.json +4 -1
package/dist/index.js CHANGED
@@ -23,6 +23,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  mod
24
24
  ));
25
25
 
26
+ // src/index.ts
27
+ var fs2 = __toESM(require("fs"));
28
+ var path2 = __toESM(require("path"));
29
+
26
30
  // src/prompts.ts
27
31
  var readline = __toESM(require("readline"));
28
32
  var DEFAULTS = {
@@ -67,917 +71,7 @@ function defaultAnswers(projectName) {
67
71
  var fs = __toESM(require("fs"));
68
72
  var path = __toESM(require("path"));
69
73
  var import_node_child_process = require("child_process");
70
- function configTemplate(answers) {
71
- return JSON.stringify({
72
- project: {
73
- name: answers.name,
74
- description: answers.description,
75
- objective: answers.objective
76
- },
77
- metrics: {
78
- command: answers.metricsCommand,
79
- fixtures: [],
80
- tracked: {}
81
- },
82
- build: {
83
- pre_measure: answers.buildPre || null,
84
- post_measure: answers.buildPost || null
85
- },
86
- cycle: {
87
- compression_interval: 5,
88
- circuit_breaker_threshold: 3,
89
- require_doubt_before_verify: true,
90
- require_challenge_before_verify: false,
91
- auto_baseline_on_new_experiment: true
92
- },
93
- models: {
94
- builder: "opus",
95
- critic: "opus",
96
- adversary: "opus",
97
- verifier: "opus",
98
- reframer: "opus",
99
- compressor: "opus",
100
- gatekeeper: "sonnet",
101
- scout: "opus"
102
- }
103
- }, null, 2);
104
- }
105
- var AGENTS = {
106
- builder: `---
107
- name: builder
108
- model: opus
109
- tools: [Read, Write, Edit, Bash, Glob, Grep]
110
- ---
111
- You are the Builder. You write code, run experiments, and make technical decisions.
112
-
113
- Before building:
114
- 1. Read docs/synthesis/current.md for project state \u2014 this IS ground truth. Trust it.
115
- 2. Read the dead-ends provided in your context \u2014 these are structural constraints.
116
- 3. Read the experiment doc for this experiment \u2014 it has your hypothesis.
117
-
118
- The synthesis already contains the diagnosis. Do NOT re-diagnose. Do NOT run
119
- exploratory scripts to "understand the problem." The classify/doubt/challenge
120
- cycle already did that work. Your job is to read the synthesis, read the code
121
- at the specific sites mentioned, and implement the fix.
122
-
123
- Read source code at the specific locations relevant to your change. Do NOT
124
- read the entire codebase or run diagnostic Python scripts. If the synthesis
125
- says "lines 1921-22" then read those lines and their context. That's it.
126
-
127
- Do NOT read raw data files (fixtures/, ground truth JSON/STL). The synthesis
128
- has the relevant facts. Reading raw data wastes turns re-deriving what the
129
- doubt/challenge/verify cycle already established.
130
-
131
- ## The Rule: ONE Change, Then Document
132
-
133
- You make ONE code change per cycle. Not two, not "one more quick fix." ONE.
134
-
135
- The sequence:
136
- 1. **Read synthesis + experiment doc** \u2014 3-4 turns max.
137
- 2. **Read code at specific sites** \u2014 2-3 turns max.
138
- 3. **Write the experiment doc FIRST** \u2014 before coding, fill in the Approach section
139
- with what you plan to do and why. This ensures there is always a record.
140
- 4. **Implement ONE focused change** \u2014 a single coherent edit to the codebase.
141
- 5. **Run the benchmark ONCE** \u2014 observe the result.
142
- 6. **Update the experiment doc** \u2014 fill in Results and Metrics with what happened.
143
- 7. **Output the majlis-json block** \u2014 your structured decisions.
144
- 8. **STOP.**
145
-
146
- After the benchmark: ONLY steps 6-7-8. No investigating why it failed. No reading
147
- stderr. No "just checking one thing." Record the numbers, write your interpretation,
148
- output the JSON, DONE. Diagnosing failures is the critic's and adversary's job.
149
-
150
- If your change doesn't work, document what happened and STOP. Do NOT try to fix it.
151
- Do NOT iterate. Do NOT "try one more thing." The adversary, critic, and verifier
152
- exist to diagnose what went wrong. The cycle comes back to you with their insights.
153
-
154
- ## Off-limits (DO NOT modify)
155
- - \`fixtures/\` \u2014 test data, ground truth, STL files. Read-only.
156
- - \`scripts/benchmark.py\` \u2014 the measurement tool. Never change how you're measured.
157
- - \`.majlis/\` \u2014 framework config. Not your concern.
158
-
159
- ## Git Safety
160
- NEVER use \`git stash\`, \`git checkout\`, \`git reset\`, or any git command that modifies
161
- the working tree or index. The \`.majlis/majlis.db\` database is in the working tree \u2014
162
- these commands will corrupt framework state. Use \`git diff\` and \`git show\` for read-only comparison.
163
-
164
- ## Confirmed Doubts
165
- If your context includes confirmedDoubts, these are weaknesses that the verifier has
166
- confirmed from a previous cycle. You MUST address each one. Do not ignore them \u2014
167
- the verifier will check again.
168
-
169
- ## Metrics
170
- The framework captures baseline and post-build metrics automatically. Do NOT claim
171
- specific metric numbers unless quoting framework output. Do NOT run the benchmark
172
- yourself unless instructed to. If you need to verify your change works, do a minimal
173
- targeted test, not a full benchmark run.
174
-
175
- ## During building:
176
- - Tag EVERY decision: proof / test / strong-consensus / consensus / analogy / judgment
177
- - When making judgment-level decisions, state: "This is judgment \u2014 reasoning without precedent"
178
-
179
- ## CRITICAL: You MUST finish cleanly.
180
-
181
- If you are running low on turns, STOP coding and immediately:
182
- 1. Update the experiment doc with whatever results you have
183
- 2. Output the <!-- majlis-json --> block
184
-
185
- The framework CANNOT recover your work if you get truncated without structured output.
186
- An incomplete experiment doc with honest "did not finish" notes is infinitely better
187
- than a truncated run with no output. Budget your turns: ~8 turns for reading,
188
- ~10 turns for coding + benchmark, ~5 turns for documentation. If you've used 35+
189
- turns, wrap up NOW regardless of where you are.
190
-
191
- You may NOT verify your own work or mark your own decisions as proven.
192
- Output your decisions in structured format so they can be recorded in the database.
193
-
194
- ## Structured Output Format
195
- At the end of your work, include a <!-- majlis-json --> block with your decisions:
196
- \`\`\`
197
- <!-- majlis-json
198
- {
199
- "decisions": [
200
- { "description": "...", "evidence_level": "judgment|test|proof|analogy|consensus|strong_consensus", "justification": "..." }
201
- ]
202
- }
203
- -->
204
- \`\`\``,
205
- critic: `---
206
- name: critic
207
- model: opus
208
- tools: [Read, Glob, Grep]
209
- ---
210
- You are the Critic. You practise constructive doubt.
211
-
212
- You receive:
213
- - The builder's experiment document (the artifact, not the reasoning chain)
214
- - The current synthesis (project state)
215
- - Dead-ends (approaches that have been tried and failed)
216
- - The hypothesis and experiment metadata
217
-
218
- You do NOT see the builder's reasoning chain \u2014 only their documented output.
219
- Use the experiment doc, synthesis, and dead-ends to find weaknesses.
220
-
221
- For each doubt:
222
- - What specific claim, decision, or assumption you doubt
223
- - WHY: reference a prior experiment, inconsistency, untested case, or false analogy
224
- - Evidence level of the doubted decision
225
- - Severity: minor / moderate / critical
226
-
227
- Rules:
228
- - Every doubt MUST reference evidence. "This feels wrong" is not a doubt.
229
- - You may NOT suggest fixes. Identify problems only.
230
- - Focus on judgment and analogy-level decisions first.
231
- - You may NOT modify any files. Produce your doubt document as output only.
232
- - Do NOT attempt to write files. The framework saves your output automatically.
233
-
234
- ## Structured Output Format
235
- <!-- majlis-json
236
- {
237
- "doubts": [
238
- { "claim_doubted": "...", "evidence_level_of_claim": "judgment", "evidence_for_doubt": "...", "severity": "critical|moderate|minor" }
239
- ]
240
- }
241
- -->`,
242
- adversary: `---
243
- name: adversary
244
- model: opus
245
- tools: [Read, Glob, Grep]
246
- ---
247
- You are the Adversary. You do NOT review code for bugs.
248
- You reason about problem structure to CONSTRUCT pathological cases.
249
-
250
- You receive:
251
- - The git diff of the builder's code changes (the actual code, not prose)
252
- - The current synthesis (project state)
253
- - The hypothesis and experiment metadata
254
-
255
- Study the CODE DIFF carefully \u2014 that is where the builder's assumptions are exposed.
256
-
257
- For each approach the builder takes, ask:
258
- - What input would make this fail?
259
- - What boundary condition was not tested?
260
- - What degenerate case collapses a distinction the algorithm relies on?
261
- - What distribution shift invalidates the assumptions?
262
- - Under what conditions do two things the builder treats as distinct become identical?
263
-
264
- Produce constructed counterexamples with reasoning.
265
- Do NOT suggest fixes. Do NOT modify files. Do NOT attempt to write files.
266
- The framework saves your output automatically.
267
-
268
- ## Structured Output Format
269
- <!-- majlis-json
270
- {
271
- "challenges": [
272
- { "description": "...", "reasoning": "..." }
273
- ]
274
- }
275
- -->`,
276
- verifier: `---
277
- name: verifier
278
- model: opus
279
- tools: [Read, Glob, Grep, Bash]
280
- ---
281
- You are the Verifier. Perform dual verification:
282
-
283
- You receive:
284
- - All doubts with explicit DOUBT-{id} identifiers (use these in your doubt_resolutions)
285
- - Challenge documents from the adversary
286
- - Framework-captured metrics (baseline vs post-build) \u2014 this is GROUND TRUTH
287
- - The hypothesis and experiment metadata
288
-
289
- ## Scope Constraint (CRITICAL)
290
-
291
- You must produce your structured output (grades + doubt resolutions) within your turn budget.
292
- Do NOT exhaustively test every doubt and challenge \u2014 prioritize the critical ones.
293
- For each doubt/challenge: one targeted check is enough. Confirm, dismiss, or mark inconclusive.
294
- Reserve your final turns for writing the structured majlis-json output.
295
-
296
- The framework saves your output automatically. Do NOT attempt to write files.
297
-
298
- ## Metrics (GROUND TRUTH)
299
- If framework-captured metrics are in your context, these are the canonical before/after numbers.
300
- Do NOT trust numbers claimed by the builder \u2014 compare against the framework metrics.
301
- If the builder claims improvement but the framework metrics show regression, flag this.
302
-
303
- ## Git Safety (CRITICAL)
304
-
305
- NEVER use \`git stash\`, \`git checkout\`, \`git reset\`, or any git command that modifies
306
- the working tree or index. The \`.majlis/majlis.db\` SQLite database is in the working tree \u2014
307
- stashing or checking out files will corrupt it and silently break the framework's state.
308
-
309
- To compare against baseline code, use read-only git commands:
310
- - \`git show main:path/to/file\` \u2014 read a file as it was on main
311
- - \`git diff main -- path/to/file\` \u2014 see what changed
312
- - \`git log --oneline main..HEAD\` \u2014 see commits on the branch
313
-
314
- To verify baseline metrics, run the benchmark on the CURRENT code and compare with the
315
- documented baseline in docs/synthesis/current.md. Do NOT stash changes to re-run baseline.
316
-
317
- ## PROVENANCE CHECK:
318
- - Can every piece of code trace to an experiment or decision?
319
- - Is the chain unbroken from requirement -> classification -> experiment -> code?
320
- - Flag any broken chains.
321
-
322
- ## CONTENT CHECK:
323
- - Does the code do what the experiment log says?
324
- - Run at most 3-5 targeted diagnostic scripts, focused on the critical doubts/challenges.
325
- - Do NOT run exhaustive diagnostics on every claim.
326
-
327
- Framework-captured metrics are ground truth \u2014 if they show regression, that
328
- alone justifies a "rejected" grade. Do not re-derive from raw fixture data.
329
-
330
- Grade each component: sound / good / weak / rejected
331
- Grade each doubt/challenge: confirmed / dismissed (with evidence) / inconclusive
332
-
333
- ## Structured Output Format
334
- IMPORTANT: For doubt_resolutions, use the DOUBT-{id} numbers from your context.
335
- Example: if your context lists "DOUBT-7: [critical] The algorithm fails on X",
336
- use doubt_id: 7 in your output.
337
-
338
- <!-- majlis-json
339
- {
340
- "grades": [
341
- { "component": "...", "grade": "sound|good|weak|rejected", "provenance_intact": true, "content_correct": true, "notes": "..." }
342
- ],
343
- "doubt_resolutions": [
344
- { "doubt_id": 7, "resolution": "confirmed|dismissed|inconclusive" }
345
- ]
346
- }
347
- -->`,
348
- reframer: `---
349
- name: reframer
350
- model: opus
351
- tools: [Read, Glob, Grep]
352
- ---
353
- You are the Reframer. You receive ONLY:
354
- - The original problem statement
355
- - The current classification document
356
- - The synthesis and dead-end registry
357
-
358
- You do NOT read builder code, experiments, or solutions.
359
-
360
- Independently propose:
361
- - How should this problem be decomposed?
362
- - What are the natural joints?
363
- - What analogies from other domains apply?
364
- - What framework would a different field use?
365
-
366
- Compare your decomposition with the existing classification.
367
- Flag structural divergences \u2014 these are the most valuable signals.
368
-
369
- Produce your reframe document as output. Do NOT attempt to write files.
370
- The framework saves your output automatically.
371
-
372
- ## Structured Output Format
373
- <!-- majlis-json
374
- {
375
- "reframe": {
376
- "decomposition": "How you decomposed the problem",
377
- "divergences": ["List of structural divergences from current classification"],
378
- "recommendation": "What should change based on your independent analysis"
379
- }
380
- }
381
- -->`,
382
- compressor: `---
383
- name: compressor
384
- model: opus
385
- tools: [Read, Write, Edit, Glob, Grep]
386
- ---
387
- You are the Compressor. Hold the entire project in view and compress it.
388
-
389
- Your taskPrompt includes a "Structured Data (CANONICAL)" section exported directly
390
- from the SQLite database. This is the source of truth. docs/ files are agent artifacts
391
- that may contain stale or incorrect information. Cross-reference everything against
392
- the database export.
393
-
394
- 1. Read the database export in your context FIRST \u2014 it has all experiments, decisions,
395
- doubts (with resolutions), verifications (with grades), challenges, and dead-ends.
396
- 2. Read docs/ files for narrative context, but trust the database when they conflict.
397
- 3. Cross-reference: same question in different language? contradicting decisions?
398
- workaround masking root cause?
399
- 4. Update fragility map: thin coverage, weak components, untested judgment
400
- decisions, broken provenance.
401
- 5. Update dead-end registry: compress rejected experiments into structural constraints.
402
- Mark each dead-end as [structural] or [procedural].
403
- 6. REWRITE synthesis using the Write tool \u2014 shorter and denser. If it's growing,
404
- you're accumulating, not compressing. You MUST use the Write tool to update
405
- docs/synthesis/current.md, docs/synthesis/fragility.md, and docs/synthesis/dead-ends.md.
406
- The framework does NOT auto-save your output for these files.
407
- 7. Review classification: new sub-types? resolved sub-types?
408
-
409
- You may ONLY write to these three files:
410
- - docs/synthesis/current.md
411
- - docs/synthesis/fragility.md
412
- - docs/synthesis/dead-ends.md
413
-
414
- Do NOT modify MEMORY.md, .claude/, classification/, experiments/, or any other paths.
415
-
416
- You may NOT write code, make decisions, or run experiments.
417
-
418
- ## Structured Output Format
419
- <!-- majlis-json
420
- {
421
- "compression_report": {
422
- "synthesis_delta": "What changed in synthesis and why",
423
- "new_dead_ends": ["List of newly identified dead-end constraints"],
424
- "fragility_changes": ["List of changes to the fragility map"]
425
- }
426
- }
427
- -->`,
428
- gatekeeper: `---
429
- name: gatekeeper
430
- model: sonnet
431
- tools: [Read, Glob, Grep]
432
- ---
433
- You are the Gatekeeper. You check hypotheses before expensive build cycles.
434
-
435
- Your job is a fast quality gate \u2014 prevent wasted Opus builds on hypotheses that
436
- are stale, redundant with dead-ends, or too vague to produce a focused change.
437
-
438
- ## Checks (in order)
439
-
440
- ### 1. Stale References
441
- Does the hypothesis reference specific functions, line numbers, or structures that
442
- may not exist in the current code? Read the relevant files to verify.
443
- - If references are stale, list them in stale_references.
444
-
445
- ### 2. Dead-End Overlap
446
- Does this hypothesis repeat an approach already ruled out by structural dead-ends?
447
- Check each structural dead-end in your context \u2014 if the hypothesis matches the
448
- approach or violates the structural_constraint, flag it.
449
- - If overlapping, list the dead-end IDs in overlapping_dead_ends.
450
-
451
- ### 3. Scope Check
452
- Is this a single focused change? A good hypothesis names ONE function, mechanism,
453
- or parameter to change. A bad hypothesis says "improve X and also Y and also Z."
454
- - Flag if the hypothesis tries to do multiple things.
455
-
456
- ## Output
457
-
458
- gate_decision:
459
- - **approve** \u2014 all checks pass, proceed to build
460
- - **flag** \u2014 concerns found but not blocking (warnings only)
461
- - **reject** \u2014 hypothesis must be revised (stale refs, dead-end repeat, or too vague)
462
-
463
- ## Structured Output Format
464
- <!-- majlis-json
465
- {
466
- "gate_decision": "approve|reject|flag",
467
- "reason": "Brief explanation of decision",
468
- "stale_references": ["list of stale references found, if any"],
469
- "overlapping_dead_ends": [0]
470
- }
471
- -->`,
472
- scout: `---
473
- name: scout
474
- model: opus
475
- tools: [Read, Glob, Grep, WebSearch]
476
- ---
477
- You are the Scout. You practise rihla \u2014 travel in search of knowledge.
478
-
479
- Your job is to search externally for alternative approaches, contradictory evidence,
480
- and perspectives from other fields that could inform the current experiment.
481
-
482
- You receive:
483
- - The current synthesis and fragility map
484
- - Dead-ends (approaches that have been tried and failed) \u2014 search for alternatives that circumvent these
485
- - The hypothesis and experiment metadata
486
-
487
- For the given experiment:
488
- 1. Describe the problem in domain-neutral terms
489
- 2. Search for alternative approaches in other fields or frameworks
490
- 3. Identify known limitations of the current approach from external sources
491
- 4. Find structurally similar problems in unrelated domains
492
- 5. Report what you find on its own terms \u2014 do not judge or filter
493
-
494
- Rules:
495
- - Present findings neutrally. Report each approach on its own terms.
496
- - Note where external approaches contradict the current one \u2014 these are the most valuable signals.
497
- - Focus on approaches that CIRCUMVENT known dead-ends \u2014 these are the most valuable.
498
- - You may NOT modify code or make decisions. Produce your rihla document as output only.
499
- - Do NOT attempt to write files. The framework saves your output automatically.
500
-
501
- ## Structured Output Format
502
- <!-- majlis-json
503
- {
504
- "findings": [
505
- { "approach": "Name of alternative approach", "source": "Where you found it", "relevance": "How it applies", "contradicts_current": true }
506
- ]
507
- }
508
- -->`,
509
- diagnostician: `---
510
- name: diagnostician
511
- model: opus
512
- tools: [Read, Write, Bash, Glob, Grep, WebSearch]
513
- ---
514
- You are the Diagnostician. You perform deep project-wide analysis.
515
-
516
- You have the highest turn budget of any agent. Use it for depth, not breadth.
517
- Your job is pure insight \u2014 you do NOT fix code, you do NOT build, you do NOT
518
- make decisions. You diagnose.
519
-
520
- ## What You Receive
521
- - Full database export: every experiment, decision, doubt, challenge, verification,
522
- dead-end, metric, and compression across the entire project history
523
- - Current synthesis, fragility map, and dead-end registry
524
- - Full read access to the entire project codebase
525
- - Bash access to run tests, profiling, git archaeology, and analysis scripts
526
-
527
- ## What You Can Do
528
- 1. **Read everything** \u2014 source code, docs, git history, test output
529
- 2. **Run analysis** \u2014 execute tests, profilers, git log/blame/bisect, custom scripts
530
- 3. **Write analysis scripts** \u2014 you may write scripts ONLY to \`.majlis/scripts/\`
531
- 4. **Search externally** \u2014 WebSearch for patterns, known issues, relevant techniques
532
-
533
- ## What You CANNOT Do
534
- - Modify any project files outside \`.majlis/scripts/\`
535
- - Make code changes, fixes, or patches
536
- - Create experiments or make decisions
537
- - Write to docs/, src/, or any other project directory
538
-
539
- ## Your Approach
540
-
541
- Phase 1: Orientation (turns 1-10)
542
- - Read the full database export in your context
543
- - Read synthesis, fragility, dead-ends
544
- - Identify patterns: recurring failures, unresolved doubts, evidence gaps
545
-
546
- Phase 2: Deep Investigation (turns 11-40)
547
- - Read source code at critical points identified in Phase 1
548
- - Run targeted tests, profiling, git archaeology
549
- - Write and execute analysis scripts in .majlis/scripts/
550
- - Cross-reference findings across experiments
551
-
552
- Phase 3: Synthesis (turns 41-60)
553
- - Compile findings into a diagnostic report
554
- - Identify root causes, not symptoms
555
- - Rank issues by structural impact
556
- - Suggest investigation directions (not fixes)
557
-
558
- ## Output Format
559
- Produce a diagnostic report as markdown. At the end, include:
560
-
561
- <!-- majlis-json
562
- {
563
- "diagnosis": {
564
- "root_causes": ["List of identified root causes"],
565
- "patterns": ["Recurring patterns across experiments"],
566
- "evidence_gaps": ["What we don't know but should"],
567
- "investigation_directions": ["Suggested directions for next experiments"]
568
- }
569
- }
570
- -->
571
-
572
- ## Safety Reminders
573
- - You are READ-ONLY for project code. Write ONLY to .majlis/scripts/.
574
- - Focus on diagnosis, not fixing. Your value is insight, not implementation.
575
- - Trust the database export over docs/ files when they conflict.`
576
- };
577
- var COMMANDS = {
578
- classify: {
579
- description: "Classify a problem domain into canonical sub-types before building",
580
- body: `Run \`majlis classify "$ARGUMENTS"\` and follow its output.
581
- If the CLI is not installed, act as the Builder in classification mode.
582
- Read docs/synthesis/current.md and docs/synthesis/dead-ends.md for context.
583
- Enumerate and classify all canonical sub-types of: $ARGUMENTS
584
- Produce a classification document following docs/classification/_TEMPLATE.md.`
585
- },
586
- doubt: {
587
- description: "Run a constructive doubt pass on an experiment",
588
- body: `Run \`majlis doubt $ARGUMENTS\` to spawn the critic agent.
589
- If the CLI is not installed, act as the Critic directly.
590
- Doubt the experiment at $ARGUMENTS. Produce a doubt document
591
- following docs/doubts/_TEMPLATE.md.`
592
- },
593
- challenge: {
594
- description: "Construct adversarial test cases for an experiment",
595
- body: `Run \`majlis challenge $ARGUMENTS\` to spawn the adversary agent.
596
- If the CLI is not installed, act as the Adversary directly.
597
- Construct pathological inputs designed to break the approach in $ARGUMENTS.
598
- Produce a challenge document following docs/challenges/_TEMPLATE.md.`
599
- },
600
- verify: {
601
- description: "Verify correctness and provenance of an experiment",
602
- body: `Run \`majlis verify $ARGUMENTS\` to spawn the verifier agent.
603
- If the CLI is not installed, act as the Verifier directly.
604
- Perform dual verification (provenance + content) on $ARGUMENTS.
605
- Produce a verification report following docs/verification/_TEMPLATE.md.`
606
- },
607
- reframe: {
608
- description: "Independently reframe a problem from scratch",
609
- body: `Run \`majlis reframe $ARGUMENTS\` to spawn the reframer agent.
610
- If the CLI is not installed, act as the Reframer directly.
611
- You receive ONLY the problem statement and classification \u2014 NOT builder code.
612
- Independently decompose $ARGUMENTS and compare with existing classification.`
613
- },
614
- compress: {
615
- description: "Compress project state into dense synthesis",
616
- body: `Run \`majlis compress\` to spawn the compressor agent.
617
- If the CLI is not installed, act as the Compressor directly.
618
- Read everything. Rewrite docs/synthesis/current.md shorter and denser.
619
- Update fragility map and dead-end registry.`
620
- },
621
- scout: {
622
- description: "Search externally for alternative approaches",
623
- body: `Run \`majlis scout $ARGUMENTS\` to spawn the scout agent.
624
- If the CLI is not installed, search for alternative approaches to $ARGUMENTS.
625
- Look for: limitations of current approach, alternative formulations from other fields,
626
- structurally similar problems in unrelated domains.
627
- Produce a rihla document at docs/rihla/.`
628
- },
629
- audit: {
630
- description: "Maqasid check \u2014 is the frame right?",
631
- body: `Run \`majlis audit "$ARGUMENTS"\` for a purpose audit.
632
- If the CLI is not installed, review: original objective, current classification,
633
- recent failures, dead-ends. Ask: is the classification serving the objective?
634
- Would we decompose differently with what we now know?`
635
- },
636
- diagnose: {
637
- description: "Deep project-wide diagnostic analysis",
638
- body: `Run \`majlis diagnose $ARGUMENTS\` for deep diagnosis.
639
- If the CLI is not installed, perform a deep diagnostic analysis.
640
- Read docs/synthesis/current.md, fragility.md, dead-ends.md, and all experiments.
641
- Identify root causes, recurring patterns, evidence gaps, and investigation directions.
642
- Do NOT modify project code \u2014 analysis only.`
643
- }
644
- };
645
- var HOOKS_CONFIG = {
646
- hooks: {
647
- SessionStart: [
648
- {
649
- hooks: [
650
- {
651
- type: "command",
652
- command: "majlis status --json 2>/dev/null || true"
653
- }
654
- ]
655
- }
656
- ],
657
- PreToolUse: [
658
- {
659
- matcher: "Bash",
660
- hooks: [
661
- {
662
- type: "command",
663
- command: "majlis check-commit 2>/dev/null || true",
664
- timeout: 10
665
- }
666
- ]
667
- }
668
- ],
669
- SubagentStop: [
670
- {
671
- hooks: [
672
- {
673
- type: "command",
674
- command: "echo 'Subagent completed. Run majlis next to continue the cycle.'",
675
- timeout: 5
676
- }
677
- ]
678
- }
679
- ]
680
- }
681
- };
682
- function claudeMdContent(name, objective) {
683
- return `# ${name}
684
-
685
- ${objective ? `**Objective:** ${objective}
686
- ` : ""}
687
- ## Majlis Protocol
688
-
689
- This project uses the Majlis Framework for structured multi-agent problem solving.
690
- See \`docs/workflow.md\` for the full cycle. See \`.claude/agents/\` for role definitions (source of truth in \`.majlis/agents/\`).
691
-
692
- ### Evidence Hierarchy (tag every decision)
693
- 1. **Proof** \u2014 mathematical proof. Overturn requires error in proof.
694
- 2. **Test** \u2014 empirical test. Overturn requires showing test insufficiency.
695
- 3a. **Strong Consensus** \u2014 convergence across independent approaches.
696
- 3b. **Consensus** \u2014 agreement from same-model experiments.
697
- 4. **Analogy** \u2014 justified by similarity to prior work.
698
- 5. **Judgment** \u2014 independent reasoning without precedent.
699
-
700
- ### Session Discipline
701
- - One intent per session. Declare it with \`majlis session start "intent"\`.
702
- - Stray thoughts \u2192 Telegram (Scribe) or docs/inbox/.
703
- - Every session ends with \`majlis session end\`.
704
-
705
- ### Before Building
706
- - Read \`docs/synthesis/current.md\` for compressed project state.
707
- - Run \`majlis dead-ends --sub-type <relevant>\` for structural constraints.
708
- - Run \`majlis decisions --level judgment\` for provisional decisions to challenge.
709
-
710
- ### Compression Trigger
711
- - Run \`majlis status\` \u2014 it will warn when compression is due.
712
-
713
- ### Current State
714
- Run \`majlis status\` for live experiment state and cycle position.
715
- `;
716
- }
717
- var WORKFLOW_MD = `# Majlis Workflow \u2014 Quick Reference
718
-
719
- ## The Cycle
720
-
721
- \`\`\`
722
- 1. CLASSIFY \u2192 Taxonomy before solution (Al-Khwarizmi)
723
- 2. REFRAME \u2192 Independent decomposition (Al-Biruni)
724
- 3. GATE \u2192 Hypothesis quality check ('Ilm al-'Ilal)
725
- 4. BUILD \u2192 Write code with tagged decisions (Ijtihad)
726
- 5. CHALLENGE \u2192 Construct breaking inputs (Ibn al-Haytham)
727
- 6. DOUBT \u2192 Systematic challenge with evidence (Shukuk)
728
- 7. SCOUT \u2192 External search for alternatives (Rihla)
729
- 8. VERIFY \u2192 Provenance + content checks (Isnad + Matn)
730
- 9. RESOLVE \u2192 Route based on grades
731
- 10. COMPRESS \u2192 Shorter and denser (Hifz)
732
- \`\`\`
733
-
734
- ## Resolution
735
- - **Sound** \u2192 Merge
736
- - **Good** \u2192 Merge + add gaps to fragility map
737
- - **Weak** \u2192 Cycle back with synthesised guidance
738
- - **Rejected** \u2192 Dead-end with structural constraint
739
-
740
- ## Circuit Breaker
741
- 3+ weak/rejected on same sub-type \u2192 Maqasid Check (purpose audit)
742
-
743
- ## Evidence Hierarchy
744
- 1. Proof \u2192 2. Test \u2192 3a. Strong Consensus \u2192 3b. Consensus \u2192 4. Analogy \u2192 5. Judgment
745
-
746
- ## Commands
747
- | Action | Command |
748
- |--------|---------|
749
- | Initialize | \`majlis init\` |
750
- | Status | \`majlis status\` |
751
- | New experiment | \`majlis new "hypothesis"\` |
752
- | Baseline metrics | \`majlis baseline\` |
753
- | Measure metrics | \`majlis measure\` |
754
- | Compare metrics | \`majlis compare\` |
755
- | Next step | \`majlis next\` |
756
- | Auto cycle | \`majlis next --auto\` |
757
- | Autonomous | \`majlis run "goal"\` |
758
- | Session start | \`majlis session start "intent"\` |
759
- | Session end | \`majlis session end\` |
760
- | Compress | \`majlis compress\` |
761
- | Audit | \`majlis audit "objective"\` |
762
- `;
763
- var DOC_TEMPLATES = {
764
- "experiments/_TEMPLATE.md": `# Experiment: {{title}}
765
-
766
- **Hypothesis:** {{hypothesis}}
767
- **Branch:** {{branch}}
768
- **Status:** {{status}}
769
- **Sub-type:** {{sub_type}}
770
- **Created:** {{date}}
771
-
772
- ## Approach
773
-
774
- [Describe the approach]
775
-
776
- ## Decisions
777
-
778
- - [evidence_level] Decision description \u2014 justification
779
-
780
- ## Results
781
-
782
- [Describe the results]
783
-
784
- ## Metrics
785
-
786
- | Fixture | Metric | Before | After | Delta |
787
- |---------|--------|--------|-------|-------|
788
- | | | | | |
789
-
790
- <!-- majlis-json
791
- {
792
- "decisions": [],
793
- "grades": []
794
- }
795
- -->
796
- `,
797
- "decisions/_TEMPLATE.md": `# Decision: {{title}}
798
-
799
- **Evidence Level:** {{evidence_level}}
800
- **Experiment:** {{experiment}}
801
- **Date:** {{date}}
802
-
803
- ## Description
804
-
805
- [What was decided]
806
-
807
- ## Justification
808
-
809
- [Why this decision was made, referencing evidence]
810
-
811
- ## Alternatives Considered
812
-
813
- [What else was considered and why it was rejected]
814
-
815
- <!-- majlis-json
816
- {
817
- "decisions": [
818
- { "description": "", "evidence_level": "", "justification": "" }
819
- ]
820
- }
821
- -->
822
- `,
823
- "classification/_TEMPLATE.md": `# Classification: {{domain}}
824
-
825
- **Date:** {{date}}
826
-
827
- ## Problem Domain
828
-
829
- [Describe the problem domain]
830
-
831
- ## Sub-Types
832
-
833
- ### 1. {{sub_type_1}}
834
- - **Description:**
835
- - **Canonical form:**
836
- - **Known constraints:**
837
-
838
- ### 2. {{sub_type_2}}
839
- - **Description:**
840
- - **Canonical form:**
841
- - **Known constraints:**
842
-
843
- ## Relationships
844
-
845
- [How sub-types relate to each other]
846
- `,
847
- "doubts/_TEMPLATE.md": `# Doubt Document \u2014 Against Experiment {{experiment}}
848
-
849
- **Critic:** {{agent}}
850
- **Date:** {{date}}
851
-
852
- ## Doubt 1: {{title}}
853
-
854
- **Claim doubted:** {{claim}}
855
- **Evidence level of claim:** {{evidence_level}}
856
- **Severity:** {{severity}}
857
-
858
- **Evidence for doubt:**
859
- [Specific evidence \u2014 a prior experiment, inconsistency, untested case, or false analogy]
860
-
861
- <!-- majlis-json
862
- {
863
- "doubts": [
864
- { "claim_doubted": "", "evidence_level_of_claim": "", "evidence_for_doubt": "", "severity": "critical" }
865
- ]
866
- }
867
- -->
868
- `,
869
- "challenges/_TEMPLATE.md": `# Challenge Document \u2014 Against Experiment {{experiment}}
870
-
871
- **Adversary:** {{agent}}
872
- **Date:** {{date}}
873
-
874
- ## Challenge 1: {{title}}
875
-
876
- **Constructed case:**
877
- [Specific input or condition designed to break the approach]
878
-
879
- **Reasoning:**
880
- [Why this case should break the approach \u2014 what assumption does it violate?]
881
-
882
- ## Challenge 2: {{title}}
883
-
884
- **Constructed case:**
885
- [Specific input or condition]
886
-
887
- **Reasoning:**
888
- [Why this should break]
889
-
890
- <!-- majlis-json
891
- {
892
- "challenges": [
893
- { "description": "", "reasoning": "" }
894
- ]
895
- }
896
- -->
897
- `,
898
- "verification/_TEMPLATE.md": `# Verification Report \u2014 Experiment {{experiment}}
899
-
900
- **Verifier:** {{agent}}
901
- **Date:** {{date}}
902
-
903
- ## Provenance Check (Isnad)
904
-
905
- | Component | Traceable | Chain intact | Notes |
906
- |-----------|-----------|--------------|-------|
907
- | | yes/no | yes/no | |
908
-
909
- ## Content Check (Matn)
910
-
911
- | Component | Tests pass | Consistent | Grade | Notes |
912
- |-----------|-----------|------------|-------|-------|
913
- | | yes/no | yes/no | sound/good/weak/rejected | |
914
-
915
- ## Doubt Resolution
916
-
917
- | Doubt | Resolution | Evidence |
918
- |-------|------------|----------|
919
- | | confirmed/dismissed/inconclusive | |
920
-
921
- <!-- majlis-json
922
- {
923
- "grades": [
924
- { "component": "", "grade": "sound", "provenance_intact": true, "content_correct": true, "notes": "" }
925
- ],
926
- "doubt_resolutions": [
927
- { "doubt_id": 0, "resolution": "confirmed" }
928
- ]
929
- }
930
- -->
931
- `,
932
- "reframes/_TEMPLATE.md": `# Reframe: {{domain}}
933
-
934
- **Reframer:** {{agent}}
935
- **Date:** {{date}}
936
-
937
- ## Independent Decomposition
938
-
939
- [How this problem should be decomposed \u2014 without seeing the builder's approach]
940
-
941
- ## Natural Joints
942
-
943
- [Where does this problem naturally divide?]
944
-
945
- ## Cross-Domain Analogies
946
-
947
- [What analogies from other domains apply?]
948
-
949
- ## Comparison with Existing Classification
950
-
951
- [Structural divergences from the current classification]
952
-
953
- ## Divergences (Most Valuable Signals)
954
-
955
- [Where the independent decomposition differs from the builder's classification]
956
- `,
957
- "rihla/_TEMPLATE.md": `# Rihla (Scout Report): {{topic}}
958
-
959
- **Date:** {{date}}
960
-
961
- ## Problem (Domain-Neutral)
962
-
963
- [Describe the problem in domain-neutral terms]
964
-
965
- ## Alternative Approaches Found
966
-
967
- ### 1. {{approach}}
968
- - **Source:**
969
- - **Description:**
970
- - **Applicability:**
971
-
972
- ## Known Limitations of Current Approach
973
-
974
- [What external sources say about where this approach fails]
975
-
976
- ## Cross-Domain Analogues
977
-
978
- [Structurally similar problems in unrelated domains]
979
- `
980
- };
74
+ var import_shared = require("@majlis/shared");
981
75
  function scaffold(opts) {
982
76
  const { targetDir, answers, fresh, noHooks, minimal } = opts;
983
77
  if (fresh) {
@@ -1034,6 +128,7 @@ function scaffoldFresh(targetDir, answers, noHooks, minimal) {
1034
128
  \x1B[32m\x1B[1mDone!\x1B[0m Project created at ${p}`);
1035
129
  console.log(`
1036
130
  cd ${targetDir}`);
131
+ console.log(" majlis scan # auto-detect project configuration");
1037
132
  console.log(" majlis status");
1038
133
  console.log(' majlis session start "First session"');
1039
134
  console.log(' majlis new "First hypothesis"\n');
@@ -1058,31 +153,32 @@ function scaffoldInit(targetDir, answers, noHooks, minimal) {
1058
153
  }
1059
154
  console.log(`
1060
155
  \x1B[32m\x1B[1mDone!\x1B[0m Majlis added to ${p}`);
1061
- console.log("\n majlis status");
156
+ console.log("\n majlis scan # auto-detect project configuration");
157
+ console.log(" majlis status");
1062
158
  console.log(' majlis session start "First session"\n');
1063
159
  }
1064
160
  function scaffoldMajlisFiles(projectRoot, answers, noHooks, minimal) {
1065
- const agentNames = minimal ? ["builder", "critic", "verifier", "compressor", "gatekeeper", "diagnostician"] : ["builder", "critic", "adversary", "verifier", "reframer", "compressor", "scout", "gatekeeper", "diagnostician"];
161
+ const agentNames = minimal ? ["builder", "critic", "verifier", "compressor", "gatekeeper", "diagnostician", "cartographer", "toolsmith"] : ["builder", "critic", "adversary", "verifier", "reframer", "compressor", "scout", "gatekeeper", "diagnostician", "cartographer", "toolsmith"];
1066
162
  const majlisDir = path.join(projectRoot, ".majlis");
1067
- mkdirSafe(majlisDir);
163
+ (0, import_shared.mkdirSafe)(majlisDir);
1068
164
  const configPath = path.join(majlisDir, "config.json");
1069
- writeIfMissing(configPath, configTemplate(answers));
165
+ writeIfMissing(configPath, (0, import_shared.configTemplate)(answers));
1070
166
  console.log(" Created .majlis/config.json");
1071
167
  const agentsDir = path.join(majlisDir, "agents");
1072
- mkdirSafe(agentsDir);
168
+ (0, import_shared.mkdirSafe)(agentsDir);
1073
169
  for (const name of agentNames) {
1074
- fs.writeFileSync(path.join(agentsDir, `${name}.md`), AGENTS[name]);
170
+ fs.writeFileSync(path.join(agentsDir, `${name}.md`), import_shared.AGENT_DEFINITIONS[name]);
1075
171
  }
1076
172
  console.log(` Created ${agentNames.length} agent definitions in .majlis/agents/`);
1077
173
  const claudeAgentsDir = path.join(projectRoot, ".claude", "agents");
1078
- mkdirSafe(claudeAgentsDir);
174
+ (0, import_shared.mkdirSafe)(claudeAgentsDir);
1079
175
  for (const name of agentNames) {
1080
- fs.writeFileSync(path.join(claudeAgentsDir, `${name}.md`), AGENTS[name]);
176
+ fs.writeFileSync(path.join(claudeAgentsDir, `${name}.md`), import_shared.AGENT_DEFINITIONS[name]);
1081
177
  }
1082
178
  console.log(" Copied agents to .claude/agents/");
1083
179
  const commandsDir = path.join(projectRoot, ".claude", "commands");
1084
- mkdirSafe(commandsDir);
1085
- for (const [name, cmd] of Object.entries(COMMANDS)) {
180
+ (0, import_shared.mkdirSafe)(commandsDir);
181
+ for (const [name, cmd] of Object.entries(import_shared.SLASH_COMMANDS)) {
1086
182
  if (minimal && (name === "challenge" || name === "reframe")) continue;
1087
183
  const content = `---
1088
184
  description: ${cmd.description}
@@ -1097,71 +193,44 @@ ${cmd.body}
1097
193
  if (fs.existsSync(settingsPath)) {
1098
194
  try {
1099
195
  const existing = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
1100
- existing.hooks = { ...existing.hooks, ...HOOKS_CONFIG.hooks };
196
+ existing.hooks = { ...existing.hooks, ...import_shared.HOOKS_CONFIG.hooks };
1101
197
  fs.writeFileSync(settingsPath, JSON.stringify(existing, null, 2));
1102
198
  } catch {
1103
- fs.writeFileSync(settingsPath, JSON.stringify(HOOKS_CONFIG, null, 2));
199
+ fs.writeFileSync(settingsPath, JSON.stringify(import_shared.HOOKS_CONFIG, null, 2));
1104
200
  }
1105
201
  } else {
1106
- mkdirSafe(path.join(projectRoot, ".claude"));
1107
- fs.writeFileSync(settingsPath, JSON.stringify(HOOKS_CONFIG, null, 2));
202
+ (0, import_shared.mkdirSafe)(path.join(projectRoot, ".claude"));
203
+ fs.writeFileSync(settingsPath, JSON.stringify(import_shared.HOOKS_CONFIG, null, 2));
1108
204
  }
1109
205
  console.log(" Created hooks in .claude/settings.json");
1110
206
  }
1111
207
  const docsDir = path.join(projectRoot, "docs");
1112
- const docDirs = [
1113
- "inbox",
1114
- "experiments",
1115
- "decisions",
1116
- "classification",
1117
- "doubts",
1118
- "challenges",
1119
- "verification",
1120
- "reframes",
1121
- "rihla",
1122
- "synthesis",
1123
- "diagnosis"
1124
- ];
1125
- for (const dir of docDirs) {
1126
- mkdirSafe(path.join(docsDir, dir));
208
+ for (const dir of import_shared.DOC_DIRS) {
209
+ (0, import_shared.mkdirSafe)(path.join(docsDir, dir));
1127
210
  }
1128
- for (const [relativePath, content] of Object.entries(DOC_TEMPLATES)) {
211
+ for (const [relativePath, content] of Object.entries(import_shared.DOC_TEMPLATES)) {
1129
212
  const fullPath = path.join(docsDir, relativePath);
1130
213
  writeIfMissing(fullPath, content);
1131
214
  }
1132
215
  console.log(" Created docs/ tree with templates");
1133
216
  const synthesisDir = path.join(docsDir, "synthesis");
1134
- writeIfMissing(
1135
- path.join(synthesisDir, "current.md"),
1136
- '# Project Synthesis\n\n*No experiments yet. Run `majlis new "hypothesis"` to begin.*\n'
1137
- );
1138
- writeIfMissing(
1139
- path.join(synthesisDir, "fragility.md"),
1140
- "# Fragility Map\n\n*No fragility recorded yet.*\n"
1141
- );
1142
- writeIfMissing(
1143
- path.join(synthesisDir, "dead-ends.md"),
1144
- "# Dead-End Registry\n\n*No dead-ends recorded yet.*\n"
1145
- );
1146
- writeIfMissing(path.join(docsDir, "workflow.md"), WORKFLOW_MD);
217
+ for (const [filename, content] of Object.entries(import_shared.SYNTHESIS_STARTERS)) {
218
+ writeIfMissing(path.join(synthesisDir, filename), content);
219
+ }
220
+ writeIfMissing(path.join(docsDir, "workflow.md"), import_shared.WORKFLOW_MD);
1147
221
  console.log(" Created docs/workflow.md");
1148
222
  const claudeMdPath = path.join(projectRoot, "CLAUDE.md");
1149
223
  if (fs.existsSync(claudeMdPath)) {
1150
224
  const existing = fs.readFileSync(claudeMdPath, "utf-8");
1151
225
  if (!existing.includes("## Majlis Protocol")) {
1152
- fs.writeFileSync(claudeMdPath, existing + "\n" + claudeMdContent(answers.name, answers.objective));
226
+ fs.writeFileSync(claudeMdPath, existing + "\n" + (0, import_shared.claudeMdContent)(answers.name, answers.objective));
1153
227
  console.log(" Appended Majlis Protocol to existing CLAUDE.md");
1154
228
  }
1155
229
  } else {
1156
- fs.writeFileSync(claudeMdPath, claudeMdContent(answers.name || path.basename(projectRoot), answers.objective));
230
+ fs.writeFileSync(claudeMdPath, (0, import_shared.claudeMdContent)(answers.name || path.basename(projectRoot), answers.objective));
1157
231
  console.log(" Created CLAUDE.md");
1158
232
  }
1159
233
  }
1160
- function mkdirSafe(dir) {
1161
- if (!fs.existsSync(dir)) {
1162
- fs.mkdirSync(dir, { recursive: true });
1163
- }
1164
- }
1165
234
  function writeIfMissing(filePath, content) {
1166
235
  if (!fs.existsSync(filePath)) {
1167
236
  fs.writeFileSync(filePath, content);
@@ -1169,7 +238,9 @@ function writeIfMissing(filePath, content) {
1169
238
  }
1170
239
 
1171
240
  // src/index.ts
1172
- var VERSION = "0.1.0";
241
+ var VERSION = JSON.parse(
242
+ fs2.readFileSync(path2.join(__dirname, "..", "package.json"), "utf-8")
243
+ ).version;
1173
244
  async function main() {
1174
245
  const args = process.argv.slice(2);
1175
246
  const hasFlag = (flag) => args.includes(flag);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-majlis",
3
- "version": "0.6.2",
3
+ "version": "0.7.0",
4
4
  "description": "Scaffold the Majlis Framework into a project",
5
5
  "bin": {
6
6
  "create-majlis": "./dist/index.js"
@@ -9,6 +9,9 @@
9
9
  "build": "tsup src/index.ts --format cjs --clean",
10
10
  "test": "echo 'No tests yet'"
11
11
  },
12
+ "dependencies": {
13
+ "@majlis/shared": "*"
14
+ },
12
15
  "devDependencies": {
13
16
  "@types/node": "^22.0.0",
14
17
  "tsup": "^8.0.0",