@monoes/monomindcli 1.14.7 → 1.15.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.
- package/.claude/agents/reengineer-squad/boss.md +113 -0
- package/.claude/agents/reengineer-squad/critic-architect.md +132 -0
- package/.claude/agents/reengineer-squad/git-manager.md +145 -0
- package/.claude/agents/reengineer-squad/idea-generator.md +95 -0
- package/.claude/agents/reengineer-squad/implementer.md +112 -0
- package/.claude/agents/reengineer-squad/integration-planner.md +112 -0
- package/.claude/agents/reengineer-squad/source-analyst.md +103 -0
- package/.claude/agents/reengineer-squad/target-analyst.md +118 -0
- package/.claude/agents/reengineer-squad/tester.md +105 -0
- package/.claude/commands/mastermind/master.md +35 -14
- package/.claude/helpers/handlers/capture-handler.cjs +155 -18
- package/.claude/helpers/monolean-activate.cjs +20 -0
- package/.claude/helpers/monolean-config.cjs +76 -0
- package/.claude/helpers/monolean-instructions.cjs +109 -0
- package/.claude/helpers/monolean-propagate.cjs +9 -0
- package/.claude/helpers/monolean-tracker.cjs +18 -0
- package/.claude/helpers/skill-registry.json +2 -2
- package/.claude/skills/agent-browser-testing/SKILL.md +301 -18
- package/.claude/skills/mastermind/runorg.md +69 -23
- package/.claude/skills/monodesign/SKILL.md +32 -1
- package/.claude/skills/monodesign/adapt.md +53 -0
- package/.claude/skills/monodesign/agents/monodesign-asset-producer.md +100 -0
- package/.claude/skills/monodesign/animate.md +65 -0
- package/.claude/skills/monodesign/audit.md +89 -0
- package/.claude/skills/monodesign/bolder.md +50 -0
- package/.claude/skills/monodesign/clarify.md +64 -0
- package/.claude/skills/monodesign/colorize.md +68 -0
- package/.claude/skills/monodesign/craft.md +51 -0
- package/.claude/skills/monodesign/critique.md +66 -0
- package/.claude/skills/monodesign/delight.md +47 -0
- package/.claude/skills/monodesign/distill.md +56 -0
- package/.claude/skills/monodesign/document.md +80 -0
- package/.claude/skills/monodesign/extract.md +74 -0
- package/.claude/skills/monodesign/harden.md +65 -0
- package/.claude/skills/monodesign/live.md +59 -0
- package/.claude/skills/monodesign/onboard.md +50 -0
- package/.claude/skills/monodesign/optimize.md +64 -0
- package/.claude/skills/monodesign/overdrive.md +56 -0
- package/.claude/skills/monodesign/polish.md +68 -0
- package/.claude/skills/monodesign/quieter.md +57 -0
- package/.claude/skills/monodesign/reference/antipatterns-catalog.md +248 -76
- package/.claude/skills/monodesign/reference/codex.md +107 -0
- package/.claude/skills/monodesign/reference/craft.md +3 -0
- package/.claude/skills/monodesign/reference/hooks.md +99 -0
- package/.claude/skills/monodesign/reference/image-prompts.md +12 -0
- package/.claude/skills/monodesign/shape.md +71 -0
- package/.claude/skills/monodesign/teach.md +69 -0
- package/.claude/skills/monodesign/typeset.md +59 -0
- package/.claude/skills/monolean/SKILL.md +118 -0
- package/.claude/skills/monolean-audit/SKILL.md +41 -0
- package/.claude/skills/monolean-debt/SKILL.md +46 -0
- package/.claude/skills/monolean-help/SKILL.md +60 -0
- package/.claude/skills/monolean-review/SKILL.md +57 -0
- package/bin/cli.js +3 -1
- package/dist/dashboard/server.js +137 -0
- package/dist/src/__tests__/browse-adapters.test.d.ts +2 -0
- package/dist/src/__tests__/browse-adapters.test.d.ts.map +1 -0
- package/dist/src/__tests__/browse-adapters.test.js +51 -0
- package/dist/src/__tests__/browse-adapters.test.js.map +1 -0
- package/dist/src/__tests__/browse-analyzer.test.d.ts +2 -0
- package/dist/src/__tests__/browse-analyzer.test.d.ts.map +1 -0
- package/dist/src/__tests__/browse-analyzer.test.js +68 -0
- package/dist/src/__tests__/browse-analyzer.test.js.map +1 -0
- package/dist/src/__tests__/browse-builtin-handlers.test.d.ts +2 -0
- package/dist/src/__tests__/browse-builtin-handlers.test.d.ts.map +1 -0
- package/dist/src/__tests__/browse-builtin-handlers.test.js +139 -0
- package/dist/src/__tests__/browse-builtin-handlers.test.js.map +1 -0
- package/dist/src/__tests__/browse-cdp.test.d.ts +2 -0
- package/dist/src/__tests__/browse-cdp.test.d.ts.map +1 -0
- package/dist/src/__tests__/browse-cdp.test.js +169 -0
- package/dist/src/__tests__/browse-cdp.test.js.map +1 -0
- package/dist/src/__tests__/browse-dashboard.test.d.ts +2 -0
- package/dist/src/__tests__/browse-dashboard.test.d.ts.map +1 -0
- package/dist/src/__tests__/browse-dashboard.test.js +179 -0
- package/dist/src/__tests__/browse-dashboard.test.js.map +1 -0
- package/dist/src/__tests__/browse-engine.test.d.ts +2 -0
- package/dist/src/__tests__/browse-engine.test.d.ts.map +1 -0
- package/dist/src/__tests__/browse-engine.test.js +122 -0
- package/dist/src/__tests__/browse-engine.test.js.map +1 -0
- package/dist/src/__tests__/browse-expression.test.d.ts +2 -0
- package/dist/src/__tests__/browse-expression.test.d.ts.map +1 -0
- package/dist/src/__tests__/browse-expression.test.js +54 -0
- package/dist/src/__tests__/browse-expression.test.js.map +1 -0
- package/dist/src/__tests__/browse-store.test.d.ts +2 -0
- package/dist/src/__tests__/browse-store.test.d.ts.map +1 -0
- package/dist/src/__tests__/browse-store.test.js +99 -0
- package/dist/src/__tests__/browse-store.test.js.map +1 -0
- package/dist/src/__tests__/browse-workflow-types.test.d.ts +2 -0
- package/dist/src/__tests__/browse-workflow-types.test.d.ts.map +1 -0
- package/dist/src/__tests__/browse-workflow-types.test.js +33 -0
- package/dist/src/__tests__/browse-workflow-types.test.js.map +1 -0
- package/dist/src/browser/action-builder/analyzer.d.ts +11 -0
- package/dist/src/browser/action-builder/analyzer.d.ts.map +1 -0
- package/dist/src/browser/action-builder/analyzer.js +71 -0
- package/dist/src/browser/action-builder/analyzer.js.map +1 -0
- package/dist/src/browser/action-builder/types.d.ts +47 -0
- package/dist/src/browser/action-builder/types.d.ts.map +1 -0
- package/dist/src/browser/action-builder/types.js +2 -0
- package/dist/src/browser/action-builder/types.js.map +1 -0
- package/dist/src/browser/adapters/gemini.d.ts +3 -0
- package/dist/src/browser/adapters/gemini.d.ts.map +1 -0
- package/dist/src/browser/adapters/gemini.js +16 -0
- package/dist/src/browser/adapters/gemini.js.map +1 -0
- package/dist/src/browser/adapters/google.d.ts +3 -0
- package/dist/src/browser/adapters/google.d.ts.map +1 -0
- package/dist/src/browser/adapters/google.js +17 -0
- package/dist/src/browser/adapters/google.js.map +1 -0
- package/dist/src/browser/adapters/index.d.ts +19 -0
- package/dist/src/browser/adapters/index.d.ts.map +1 -0
- package/dist/src/browser/adapters/index.js +23 -0
- package/dist/src/browser/adapters/index.js.map +1 -0
- package/dist/src/browser/adapters/instagram.d.ts +3 -0
- package/dist/src/browser/adapters/instagram.d.ts.map +1 -0
- package/dist/src/browser/adapters/instagram.js +17 -0
- package/dist/src/browser/adapters/instagram.js.map +1 -0
- package/dist/src/browser/adapters/linkedin.d.ts +3 -0
- package/dist/src/browser/adapters/linkedin.d.ts.map +1 -0
- package/dist/src/browser/adapters/linkedin.js +19 -0
- package/dist/src/browser/adapters/linkedin.js.map +1 -0
- package/dist/src/browser/adapters/microsoft.d.ts +3 -0
- package/dist/src/browser/adapters/microsoft.d.ts.map +1 -0
- package/dist/src/browser/adapters/microsoft.js +16 -0
- package/dist/src/browser/adapters/microsoft.js.map +1 -0
- package/dist/src/browser/adapters/x.d.ts +3 -0
- package/dist/src/browser/adapters/x.d.ts.map +1 -0
- package/dist/src/browser/adapters/x.js +19 -0
- package/dist/src/browser/adapters/x.js.map +1 -0
- package/dist/src/browser/dashboard/api-types.d.ts +50 -0
- package/dist/src/browser/dashboard/api-types.d.ts.map +1 -0
- package/dist/src/browser/dashboard/api-types.js +14 -0
- package/dist/src/browser/dashboard/api-types.js.map +1 -0
- package/dist/src/browser/dashboard/server.d.ts +9 -0
- package/dist/src/browser/dashboard/server.d.ts.map +1 -0
- package/dist/src/browser/dashboard/server.js +62 -0
- package/dist/src/browser/dashboard/server.js.map +1 -0
- package/dist/src/browser/dashboard/ui.html +1811 -0
- package/dist/src/browser/workflow/builtin-handlers.d.ts +3 -0
- package/dist/src/browser/workflow/builtin-handlers.d.ts.map +1 -0
- package/dist/src/browser/workflow/builtin-handlers.js +343 -0
- package/dist/src/browser/workflow/builtin-handlers.js.map +1 -0
- package/dist/src/browser/workflow/engine.d.ts +15 -0
- package/dist/src/browser/workflow/engine.d.ts.map +1 -0
- package/dist/src/browser/workflow/engine.js +127 -0
- package/dist/src/browser/workflow/engine.js.map +1 -0
- package/dist/src/browser/workflow/expression.d.ts +4 -0
- package/dist/src/browser/workflow/expression.d.ts.map +1 -0
- package/dist/src/browser/workflow/expression.js +64 -0
- package/dist/src/browser/workflow/expression.js.map +1 -0
- package/dist/src/browser/workflow/store.d.ts +24 -0
- package/dist/src/browser/workflow/store.d.ts.map +1 -0
- package/dist/src/browser/workflow/store.js +145 -0
- package/dist/src/browser/workflow/store.js.map +1 -0
- package/dist/src/browser/workflow/types.d.ts +48 -0
- package/dist/src/browser/workflow/types.d.ts.map +1 -0
- package/dist/src/browser/workflow/types.js +2 -0
- package/dist/src/browser/workflow/types.js.map +1 -0
- package/dist/src/commands/browse-action.d.ts +4 -0
- package/dist/src/commands/browse-action.d.ts.map +1 -0
- package/dist/src/commands/browse-action.js +151 -0
- package/dist/src/commands/browse-action.js.map +1 -0
- package/dist/src/commands/browse-platform.d.ts +4 -0
- package/dist/src/commands/browse-platform.d.ts.map +1 -0
- package/dist/src/commands/browse-platform.js +117 -0
- package/dist/src/commands/browse-platform.js.map +1 -0
- package/dist/src/commands/browse-workflow.d.ts +4 -0
- package/dist/src/commands/browse-workflow.d.ts.map +1 -0
- package/dist/src/commands/browse-workflow.js +153 -0
- package/dist/src/commands/browse-workflow.js.map +1 -0
- package/dist/src/commands/browse.d.ts +10 -6
- package/dist/src/commands/browse.d.ts.map +1 -1
- package/dist/src/commands/browse.js +11 -2154
- package/dist/src/commands/browse.js.map +1 -1
- package/dist/src/commands/design-detect.d.ts +21 -0
- package/dist/src/commands/design-detect.d.ts.map +1 -0
- package/dist/src/commands/design-detect.js +127 -0
- package/dist/src/commands/design-detect.js.map +1 -0
- package/dist/src/commands/design-palette.d.ts +22 -0
- package/dist/src/commands/design-palette.d.ts.map +1 -0
- package/dist/src/commands/design-palette.js +539 -0
- package/dist/src/commands/design-palette.js.map +1 -0
- package/dist/src/commands/hooks-core-commands.d.ts +10 -0
- package/dist/src/commands/hooks-core-commands.d.ts.map +1 -0
- package/dist/src/commands/hooks-core-commands.js +377 -0
- package/dist/src/commands/hooks-core-commands.js.map +1 -0
- package/dist/src/commands/hooks-coverage-commands.d.ts +12 -0
- package/dist/src/commands/hooks-coverage-commands.d.ts.map +1 -0
- package/dist/src/commands/hooks-coverage-commands.js +1217 -0
- package/dist/src/commands/hooks-coverage-commands.js.map +1 -0
- package/dist/src/commands/hooks-coverage-utils.d.ts +42 -0
- package/dist/src/commands/hooks-coverage-utils.d.ts.map +1 -0
- package/dist/src/commands/hooks-coverage-utils.js +220 -0
- package/dist/src/commands/hooks-coverage-utils.js.map +1 -0
- package/dist/src/commands/hooks-extended-commands.d.ts +14 -0
- package/dist/src/commands/hooks-extended-commands.d.ts.map +1 -0
- package/dist/src/commands/hooks-extended-commands.js +579 -0
- package/dist/src/commands/hooks-extended-commands.js.map +1 -0
- package/dist/src/commands/hooks-formatting.d.ts +13 -0
- package/dist/src/commands/hooks-formatting.d.ts.map +1 -0
- package/dist/src/commands/hooks-formatting.js +42 -0
- package/dist/src/commands/hooks-formatting.js.map +1 -0
- package/dist/src/commands/hooks-routing-commands.d.ts +15 -0
- package/dist/src/commands/hooks-routing-commands.d.ts.map +1 -0
- package/dist/src/commands/hooks-routing-commands.js +723 -0
- package/dist/src/commands/hooks-routing-commands.js.map +1 -0
- package/dist/src/commands/hooks-workers.d.ts +9 -0
- package/dist/src/commands/hooks-workers.d.ts.map +1 -0
- package/dist/src/commands/hooks-workers.js +782 -0
- package/dist/src/commands/hooks-workers.js.map +1 -0
- package/dist/src/commands/hooks.d.ts +8 -0
- package/dist/src/commands/hooks.d.ts.map +1 -1
- package/dist/src/commands/hooks.js +179 -4103
- package/dist/src/commands/hooks.js.map +1 -1
- package/dist/src/commands/index.d.ts +1 -0
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +6 -0
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/org.d.ts.map +1 -1
- package/dist/src/commands/org.js +14 -15
- package/dist/src/commands/org.js.map +1 -1
- package/dist/src/commands/tokens.d.ts.map +1 -1
- package/dist/src/commands/tokens.js +77 -1
- package/dist/src/commands/tokens.js.map +1 -1
- package/dist/src/init/executor.d.ts.map +1 -1
- package/dist/src/init/executor.js +18 -8
- package/dist/src/init/executor.js.map +1 -1
- package/dist/src/init/settings-generator.d.ts.map +1 -1
- package/dist/src/init/settings-generator.js +39 -5
- package/dist/src/init/settings-generator.js.map +1 -1
- package/dist/src/init/statusline-generator.d.ts.map +1 -1
- package/dist/src/init/statusline-generator.js +25 -5
- package/dist/src/init/statusline-generator.js.map +1 -1
- package/dist/src/mcp-tools/browser-tools.d.ts +3 -5
- package/dist/src/mcp-tools/browser-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/browser-tools.js +619 -326
- package/dist/src/mcp-tools/browser-tools.js.map +1 -1
- package/dist/src/mcp-tools/hooks-embedding.d.ts +161 -0
- package/dist/src/mcp-tools/hooks-embedding.d.ts.map +1 -0
- package/dist/src/mcp-tools/hooks-embedding.js +506 -0
- package/dist/src/mcp-tools/hooks-embedding.js.map +1 -0
- package/dist/src/mcp-tools/hooks-intelligence.d.ts +26 -0
- package/dist/src/mcp-tools/hooks-intelligence.d.ts.map +1 -0
- package/dist/src/mcp-tools/hooks-intelligence.js +1328 -0
- package/dist/src/mcp-tools/hooks-intelligence.js.map +1 -0
- package/dist/src/mcp-tools/hooks-routing.d.ts +27 -0
- package/dist/src/mcp-tools/hooks-routing.d.ts.map +1 -0
- package/dist/src/mcp-tools/hooks-routing.js +1591 -0
- package/dist/src/mcp-tools/hooks-routing.js.map +1 -0
- package/dist/src/mcp-tools/hooks-tools.d.ts +3 -38
- package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/hooks-tools.js +5 -3393
- package/dist/src/mcp-tools/hooks-tools.js.map +1 -1
- package/dist/src/mcp-tools/monograph-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/monograph-tools.js +24 -14
- package/dist/src/mcp-tools/monograph-tools.js.map +1 -1
- package/dist/src/mcp-tools/workflow-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/workflow-tools.js +54 -1
- package/dist/src/mcp-tools/workflow-tools.js.map +1 -1
- package/dist/src/memory/embedding-operations.d.ts +58 -0
- package/dist/src/memory/embedding-operations.d.ts.map +1 -0
- package/dist/src/memory/embedding-operations.js +299 -0
- package/dist/src/memory/embedding-operations.js.map +1 -0
- package/dist/src/memory/ewc-consolidation.d.ts.map +1 -1
- package/dist/src/memory/ewc-consolidation.js +37 -3
- package/dist/src/memory/ewc-consolidation.js.map +1 -1
- package/dist/src/memory/hnsw-operations.d.ts +130 -0
- package/dist/src/memory/hnsw-operations.d.ts.map +1 -0
- package/dist/src/memory/hnsw-operations.js +400 -0
- package/dist/src/memory/hnsw-operations.js.map +1 -0
- package/dist/src/memory/intelligence.d.ts.map +1 -1
- package/dist/src/memory/intelligence.js +42 -23
- package/dist/src/memory/intelligence.js.map +1 -1
- package/dist/src/memory/memory-bridge.d.ts.map +1 -1
- package/dist/src/memory/memory-bridge.js +52 -8
- package/dist/src/memory/memory-bridge.js.map +1 -1
- package/dist/src/memory/memory-crud.d.ts +67 -0
- package/dist/src/memory/memory-crud.d.ts.map +1 -0
- package/dist/src/memory/memory-crud.js +415 -0
- package/dist/src/memory/memory-crud.js.map +1 -0
- package/dist/src/memory/memory-initializer.d.ts +9 -322
- package/dist/src/memory/memory-initializer.d.ts.map +1 -1
- package/dist/src/memory/memory-initializer.js +17 -1794
- package/dist/src/memory/memory-initializer.js.map +1 -1
- package/dist/src/memory/memory-migrations.d.ts +30 -0
- package/dist/src/memory/memory-migrations.d.ts.map +1 -0
- package/dist/src/memory/memory-migrations.js +134 -0
- package/dist/src/memory/memory-migrations.js.map +1 -0
- package/dist/src/memory/memory-read.d.ts +78 -0
- package/dist/src/memory/memory-read.d.ts.map +1 -0
- package/dist/src/memory/memory-read.js +331 -0
- package/dist/src/memory/memory-read.js.map +1 -0
- package/dist/src/memory/memory-schema.d.ts +13 -0
- package/dist/src/memory/memory-schema.d.ts.map +1 -0
- package/dist/src/memory/memory-schema.js +167 -0
- package/dist/src/memory/memory-schema.js.map +1 -0
- package/dist/src/memory/sona-optimizer.d.ts.map +1 -1
- package/dist/src/memory/sona-optimizer.js +37 -4
- package/dist/src/memory/sona-optimizer.js.map +1 -1
- package/dist/src/monovector/route-outcomes.d.ts.map +1 -1
- package/dist/src/monovector/route-outcomes.js +16 -6
- package/dist/src/monovector/route-outcomes.js.map +1 -1
- package/dist/src/pricing/model-pricing.d.ts +41 -0
- package/dist/src/pricing/model-pricing.d.ts.map +1 -0
- package/dist/src/pricing/model-pricing.js +61 -0
- package/dist/src/pricing/model-pricing.js.map +1 -0
- package/dist/src/ui/.monomind/capture/active-run.json +1 -0
- package/dist/src/ui/.monomind/orgs/system-trial-qa/runs/real-events-1782290897.convs.jsonl +3 -0
- package/dist/src/ui/.monomind/orgs/system-trial-qa/runs/real-events-1782290897.jsonl +11 -0
- package/dist/src/ui/.monomind/orgs/system-trial-qa/runs/rigid-qa-restart-1782288201.jsonl +540 -0
- package/dist/src/ui/.monomind/orgs/system-trial-qa-threads.jsonl +3 -0
- package/dist/src/ui/.monomind/orgs/test-event-fix/runs/rigid-qa-restart-1782288201.jsonl +2 -0
- package/dist/src/ui/MODULARIZATION_PLAN.md +79 -0
- package/dist/src/ui/collector.mjs +23 -13
- package/dist/src/ui/dashboard.html +1653 -14
- package/dist/src/ui/data/known-projects.json +1 -0
- package/dist/src/ui/data/mastermind-events.jsonl +553 -0
- package/dist/src/ui/data/sessions/_index.json +1 -0
- package/dist/src/ui/data/sessions/final-sess-001.jsonl +542 -0
- package/dist/src/ui/data/unknown-events.jsonl +1 -0
- package/dist/src/ui/orgs.html +154 -10
- package/dist/src/ui/server.mjs +1162 -168
- package/dist/src/ui/sse-manager.mjs +119 -0
- package/dist/src/update/checker.js +1 -1
- package/dist/src/update/checker.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/workflow/builtin-handlers.js +321 -0
- package/dist/workflow/engine.js +253 -0
- package/dist/workflow/expression.js +98 -0
- package/dist/workflow/types.js +2 -0
- package/package.json +8 -6
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
//
|
|
15
15
|
// Active session awareness:
|
|
16
16
|
// - Reads .monomind/capture/active-session.json (written by server on session:start)
|
|
17
|
-
// - Reads .monomind/capture/active-run.json (written by server on run:start)
|
|
17
|
+
// - Reads .monomind/capture/active-run.json (written by server on run:start or org:start)
|
|
18
18
|
// - Includes sessionId in all emitted events so they link to the dashboard session
|
|
19
19
|
|
|
20
20
|
const fs = require('fs');
|
|
@@ -91,6 +91,16 @@ function parseJSONLForData(filePath) {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
function getActiveRun() {
|
|
94
|
+
// Phase 1: Try ppid-keyed file first — supports multiple concurrent orgs (Issue 3)
|
|
95
|
+
const ppidFile = path.join(CAPTURE_DIR, 'active-runs', `${process.ppid}.json`);
|
|
96
|
+
if (fs.existsSync(ppidFile)) {
|
|
97
|
+
try {
|
|
98
|
+
const d = JSON.parse(fs.readFileSync(ppidFile, 'utf8'));
|
|
99
|
+
if (Date.now() - (d.ts || 0) > 8 * 60 * 60 * 1000) return null;
|
|
100
|
+
return d;
|
|
101
|
+
} catch { /* fall through to single-slot fallback */ }
|
|
102
|
+
}
|
|
103
|
+
// Fallback: single-slot active-run.json (written by server on org:start)
|
|
94
104
|
const runFile = path.join(CAPTURE_DIR, 'active-run.json');
|
|
95
105
|
if (!fs.existsSync(runFile)) return null;
|
|
96
106
|
try {
|
|
@@ -101,18 +111,34 @@ function getActiveRun() {
|
|
|
101
111
|
} catch { return null; }
|
|
102
112
|
}
|
|
103
113
|
|
|
104
|
-
function getActiveSession() {
|
|
114
|
+
function getActiveSession(activeRun) {
|
|
105
115
|
const sessFile = path.join(CAPTURE_DIR, 'active-session.json');
|
|
106
|
-
if (
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
116
|
+
if (fs.existsSync(sessFile)) {
|
|
117
|
+
try {
|
|
118
|
+
const d = JSON.parse(fs.readFileSync(sessFile, 'utf8'));
|
|
119
|
+
// Treat as stale after 8 hours
|
|
120
|
+
if (Date.now() - (d.ts || 0) <= 8 * 60 * 60 * 1000) return d; // { org, sessionId, ts }
|
|
121
|
+
} catch { /* fall through to synthesis */ }
|
|
122
|
+
}
|
|
123
|
+
// Fallback: synthesize a session from active-run so agent events are always attributed,
|
|
124
|
+
// even if session:start was never emitted (LLM compliance risk). The synthetic session
|
|
125
|
+
// uses a stable ID so all events within the same run land in the same session file.
|
|
126
|
+
if (activeRun?.org && activeRun?.runId) {
|
|
127
|
+
const synthetic = { org: activeRun.org, sessionId: 'auto-' + activeRun.org + '-' + activeRun.runId, ts: Date.now(), synthetic: true };
|
|
128
|
+
try { fs.writeFileSync(sessFile, JSON.stringify(synthetic)); } catch { /* non-fatal */ }
|
|
129
|
+
return synthetic;
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
113
132
|
}
|
|
114
133
|
|
|
115
|
-
function
|
|
134
|
+
function emitEvent(event) {
|
|
135
|
+
// Phase 2: Write to spool first (dead-letter queue) — survives server restart/downtime (Issue 5)
|
|
136
|
+
const spoolDir = path.join(CAPTURE_DIR, 'spool');
|
|
137
|
+
const spoolFile = path.join(spoolDir, `${Date.now()}-${Math.random().toString(36).slice(2, 8)}.json`);
|
|
138
|
+
try {
|
|
139
|
+
fs.mkdirSync(spoolDir, { recursive: true });
|
|
140
|
+
fs.writeFileSync(spoolFile, JSON.stringify(event));
|
|
141
|
+
} catch { /* non-fatal — proceed with HTTP attempt */ }
|
|
116
142
|
return new Promise((resolve) => {
|
|
117
143
|
try {
|
|
118
144
|
const ctrlPath = path.join(CWD, '.monomind', 'control.json');
|
|
@@ -128,7 +154,10 @@ function postEvent(event) {
|
|
|
128
154
|
path: '/api/mastermind/event',
|
|
129
155
|
method: 'POST',
|
|
130
156
|
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) },
|
|
131
|
-
}, () =>
|
|
157
|
+
}, () => {
|
|
158
|
+
try { fs.unlinkSync(spoolFile); } catch {}
|
|
159
|
+
resolve();
|
|
160
|
+
});
|
|
132
161
|
req.on('error', () => resolve());
|
|
133
162
|
req.setTimeout(3000, () => { req.destroy(); resolve(); });
|
|
134
163
|
req.write(body);
|
|
@@ -148,13 +177,28 @@ async function handleSubagentStart(hookInput) {
|
|
|
148
177
|
).slice(0, 64).replace(/[^a-z0-9_-]/gi, '-');
|
|
149
178
|
const agentDesc = String(hookInput.description || hookInput.prompt_description || '').slice(0, 1000);
|
|
150
179
|
const activeRun = getActiveRun();
|
|
151
|
-
|
|
180
|
+
// Phase 1: Bootstrap ppid-keyed active-run file for multi-org support (Issue 3)
|
|
181
|
+
if (activeRun) {
|
|
182
|
+
const ppidDir = path.join(CAPTURE_DIR, 'active-runs');
|
|
183
|
+
const ppidFile = path.join(ppidDir, `${process.ppid}.json`);
|
|
184
|
+
if (!fs.existsSync(ppidFile)) {
|
|
185
|
+
try {
|
|
186
|
+
fs.mkdirSync(ppidDir, { recursive: true });
|
|
187
|
+
fs.writeFileSync(ppidFile, JSON.stringify({ ...activeRun, ppid: process.ppid }));
|
|
188
|
+
} catch { /* non-fatal */ }
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const activeSess = getActiveSession(activeRun);
|
|
152
192
|
|
|
153
193
|
// Write snapshot to FIFO queue — subagent-stop pops the oldest
|
|
154
194
|
const snapFile = path.join(
|
|
155
195
|
CAPTURE_DIR,
|
|
156
196
|
'snap-' + Date.now() + '-' + Math.random().toString(36).slice(2, 6) + '.json'
|
|
157
197
|
);
|
|
198
|
+
const leanModePath = path.join(process.env.CLAUDE_PROJECT_DIR || process.cwd(), '.monomind/state/monolean-mode');
|
|
199
|
+
let leanMode = null;
|
|
200
|
+
try { leanMode = fs.readFileSync(leanModePath, 'utf8').trim() || null; } catch {}
|
|
201
|
+
|
|
158
202
|
fs.writeFileSync(snapFile, JSON.stringify({
|
|
159
203
|
ts: Date.now(),
|
|
160
204
|
files: snapshot,
|
|
@@ -163,6 +207,7 @@ async function handleSubagentStart(hookInput) {
|
|
|
163
207
|
org: activeSess?.org || activeRun?.org || null,
|
|
164
208
|
runId: activeRun?.runId || null,
|
|
165
209
|
session: activeSess?.sessionId || null,
|
|
210
|
+
leanMode: leanMode || 'off',
|
|
166
211
|
}));
|
|
167
212
|
|
|
168
213
|
console.log('[CAPTURE:start] ' + agentType + ' · snapped ' + snapshot.length + ' files'
|
|
@@ -172,7 +217,7 @@ async function handleSubagentStart(hookInput) {
|
|
|
172
217
|
// Emit agent:spawn immediately so the dashboard shows the agent starting
|
|
173
218
|
const org = activeSess?.org || activeRun?.org;
|
|
174
219
|
if (org || activeSess?.sessionId) {
|
|
175
|
-
await
|
|
220
|
+
await emitEvent({
|
|
176
221
|
type: 'agent:spawn',
|
|
177
222
|
org: org || '',
|
|
178
223
|
runId: activeRun?.runId || '',
|
|
@@ -210,7 +255,9 @@ async function handleSubagentStop(hookInput) {
|
|
|
210
255
|
try { fs.unlinkSync(snapPath); } catch {}
|
|
211
256
|
|
|
212
257
|
// Also check current active session (may have changed since SubagentStart)
|
|
213
|
-
|
|
258
|
+
// Pass a synthetic activeRun from snap so session can be synthesized even if snap.session is null
|
|
259
|
+
const _snapRun = snap.runId ? { org: snap.org, runId: snap.runId } : null;
|
|
260
|
+
const activeSess = getActiveSession(_snapRun);
|
|
214
261
|
const session = snap.session || activeSess?.sessionId || null;
|
|
215
262
|
const org = snap.org || activeSess?.org || null;
|
|
216
263
|
const runId = snap.runId || null;
|
|
@@ -257,7 +304,7 @@ async function handleSubagentStop(hookInput) {
|
|
|
257
304
|
|
|
258
305
|
// ── Emit agent:usage (token/cost accounting) ──────────────────────────────
|
|
259
306
|
if (totalTin > 0 || totalTout > 0) {
|
|
260
|
-
await
|
|
307
|
+
await emitEvent({
|
|
261
308
|
type: 'agent:usage',
|
|
262
309
|
org: org || '',
|
|
263
310
|
runId: runId || '',
|
|
@@ -273,7 +320,7 @@ async function handleSubagentStop(hookInput) {
|
|
|
273
320
|
|
|
274
321
|
// ── Emit agent:complete (replaces org:comms — richer, includes session) ───
|
|
275
322
|
// Always emit even if summary is empty (so the spawn/complete pair is always visible)
|
|
276
|
-
await
|
|
323
|
+
await emitEvent({
|
|
277
324
|
type: 'agent:complete',
|
|
278
325
|
org: org || '',
|
|
279
326
|
runId: runId || '',
|
|
@@ -293,7 +340,7 @@ async function handleSubagentStop(hookInput) {
|
|
|
293
340
|
|
|
294
341
|
// ── Also emit legacy org:comms for backwards compat ───────────────────────
|
|
295
342
|
if (summary && (org || session)) {
|
|
296
|
-
await
|
|
343
|
+
await emitEvent({
|
|
297
344
|
type: 'org:comms',
|
|
298
345
|
org: org || '',
|
|
299
346
|
runId: runId || '',
|
|
@@ -325,12 +372,102 @@ async function handleSubagentStop(hookInput) {
|
|
|
325
372
|
}
|
|
326
373
|
}
|
|
327
374
|
|
|
375
|
+
// ─── Phase 3: PreToolUse accumulator (Issue 9) ────────────────────────────────
|
|
376
|
+
// capture-handler is short-lived — no timers. Accumulate tool calls to a
|
|
377
|
+
// persistent batch file; server polls and emits agent:read:batch events.
|
|
378
|
+
|
|
379
|
+
async function handlePreTool(hookInput) {
|
|
380
|
+
const activeRun = getActiveRun();
|
|
381
|
+
if (!activeRun) return; // no active run — nothing to attribute to
|
|
382
|
+
|
|
383
|
+
const toolName = String(hookInput.tool_name || hookInput.name || '').toLowerCase();
|
|
384
|
+
const toolInput = hookInput.tool_input || hookInput.input || {};
|
|
385
|
+
|
|
386
|
+
// Only batch file-read events; edits/bash/browse are emitted directly
|
|
387
|
+
const isRead = toolName === 'read' || toolName === 'readfile';
|
|
388
|
+
const isEdit = toolName === 'edit' || toolName === 'write' || toolName === 'multiedit';
|
|
389
|
+
const isBash = toolName === 'bash' || toolName === 'shell';
|
|
390
|
+
const isBrowse = toolName === 'browse' || toolName.includes('browse');
|
|
391
|
+
|
|
392
|
+
if (isRead) {
|
|
393
|
+
// Accumulate to batch file (server polls every 3s)
|
|
394
|
+
const batchFile = path.join(CAPTURE_DIR, `read-batch-${process.ppid}.json`);
|
|
395
|
+
let batch = [];
|
|
396
|
+
try { batch = JSON.parse(fs.readFileSync(batchFile, 'utf8')); } catch {}
|
|
397
|
+
batch.push({ path: toolInput.file_path || toolInput.path || '', ts: Date.now() });
|
|
398
|
+
try { fs.writeFileSync(batchFile, JSON.stringify(batch)); } catch {}
|
|
399
|
+
} else if (isEdit || isBash || isBrowse) {
|
|
400
|
+
// Emit directly — these are important events worth showing immediately
|
|
401
|
+
const evType = isEdit ? 'agent:edit' : isBash ? 'agent:bash' : 'agent:browse';
|
|
402
|
+
const payload = isEdit ? (toolInput.file_path || toolInput.path || '') : (toolInput.command || toolInput.url || '');
|
|
403
|
+
const activeSess = getActiveSession(activeRun);
|
|
404
|
+
await emitEvent({
|
|
405
|
+
type: evType,
|
|
406
|
+
org: activeRun.org || '',
|
|
407
|
+
runId: activeRun.runId || '',
|
|
408
|
+
session: activeSess?.sessionId || '',
|
|
409
|
+
payload: String(payload).slice(0, 256),
|
|
410
|
+
ts: Date.now(),
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// ─── Phase 4: PostToolUse — capture Bash output (test results, command output) ────
|
|
416
|
+
|
|
417
|
+
async function handlePostTool(hookInput) {
|
|
418
|
+
const activeRun = getActiveRun();
|
|
419
|
+
if (!activeRun) return;
|
|
420
|
+
|
|
421
|
+
const toolName = String(hookInput.tool_name || hookInput.name || '').toLowerCase();
|
|
422
|
+
const toolInput = hookInput.tool_input || hookInput.input || {};
|
|
423
|
+
const toolResponse = hookInput.tool_response || hookInput.response || {};
|
|
424
|
+
|
|
425
|
+
const isBash = toolName === 'bash' || toolName === 'shell';
|
|
426
|
+
const isEdit = toolName === 'edit' || toolName === 'write' || toolName === 'multiedit';
|
|
427
|
+
|
|
428
|
+
if (!isBash && !isEdit) return;
|
|
429
|
+
|
|
430
|
+
const activeSess = getActiveSession(activeRun);
|
|
431
|
+
|
|
432
|
+
if (isBash) {
|
|
433
|
+
const cmd = String(toolInput.command || toolInput.cmd || '').slice(0, 256);
|
|
434
|
+
// Capture output — tool_response may be a string or {output, error} object
|
|
435
|
+
const rawOut = typeof toolResponse === 'string' ? toolResponse
|
|
436
|
+
: (toolResponse.output || toolResponse.stdout || toolResponse.result || '');
|
|
437
|
+
const output = String(rawOut).slice(0, 1200); // cap at 1200 chars for storage
|
|
438
|
+
// Only emit if there's actual output worth showing
|
|
439
|
+
if (!cmd) return;
|
|
440
|
+
await emitEvent({
|
|
441
|
+
type: 'agent:bash',
|
|
442
|
+
org: activeRun.org || '',
|
|
443
|
+
runId: activeRun.runId || '',
|
|
444
|
+
session: activeSess?.sessionId || '',
|
|
445
|
+
payload: cmd,
|
|
446
|
+
output: output,
|
|
447
|
+
ts: Date.now(),
|
|
448
|
+
});
|
|
449
|
+
} else if (isEdit) {
|
|
450
|
+
const filePath = String(toolInput.file_path || toolInput.path || '').slice(0, 256);
|
|
451
|
+
if (!filePath) return;
|
|
452
|
+
await emitEvent({
|
|
453
|
+
type: 'agent:edit',
|
|
454
|
+
org: activeRun.org || '',
|
|
455
|
+
runId: activeRun.runId || '',
|
|
456
|
+
session: activeSess?.sessionId || '',
|
|
457
|
+
payload: filePath,
|
|
458
|
+
ts: Date.now(),
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
328
463
|
// ─── Dispatch ─────────────────────────────────────────────────────────────────
|
|
329
464
|
|
|
330
|
-
const eventType = process.argv[2]; // 'subagent-start' | 'subagent-stop'
|
|
465
|
+
const eventType = process.argv[2]; // 'subagent-start' | 'subagent-stop' | 'pretool' | 'posttool'
|
|
331
466
|
|
|
332
467
|
readStdin().then(hookInput => {
|
|
333
468
|
if (eventType === 'subagent-start') return handleSubagentStart(hookInput);
|
|
334
469
|
if (eventType === 'subagent-stop') return handleSubagentStop(hookInput);
|
|
470
|
+
if (eventType === 'pretool') return handlePreTool(hookInput);
|
|
471
|
+
if (eventType === 'posttool') return handlePostTool(hookInput);
|
|
335
472
|
console.log('[CAPTURE] unknown event type: ' + eventType);
|
|
336
473
|
}).catch(() => process.exit(0));
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { getDefaultMode, setMode, clearMode } = require('./monolean-config.cjs');
|
|
3
|
+
const { getMonoleanInstructions } = require('./monolean-instructions.cjs');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
const mode = getDefaultMode();
|
|
8
|
+
if (!mode || mode === 'off') { clearMode(); process.exit(0); }
|
|
9
|
+
|
|
10
|
+
setMode(mode);
|
|
11
|
+
|
|
12
|
+
// Write mode for statusline
|
|
13
|
+
const metricsDir = path.join(process.env.CLAUDE_PROJECT_DIR || process.cwd(), '.monomind/metrics');
|
|
14
|
+
try {
|
|
15
|
+
fs.mkdirSync(metricsDir, { recursive: true });
|
|
16
|
+
fs.writeFileSync(path.join(metricsDir, 'monolean-mode.json'), JSON.stringify({ mode, ts: Date.now() }));
|
|
17
|
+
} catch {}
|
|
18
|
+
|
|
19
|
+
const instructions = getMonoleanInstructions(mode);
|
|
20
|
+
process.stdout.write(instructions);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
|
|
5
|
+
const VALID_MODES = ['off', 'lite', 'full', 'ultra', 'review'];
|
|
6
|
+
const DEFAULT_MODE = 'full';
|
|
7
|
+
const STATE_RELPATH = '.monomind/state/monolean-mode';
|
|
8
|
+
|
|
9
|
+
// Walk up from CLAUDE_PROJECT_DIR then cwd to find the project root containing the state file.
|
|
10
|
+
// Required for SubagentStart hooks where CLAUDE_PROJECT_DIR may differ from the parent project.
|
|
11
|
+
function findStateFile() {
|
|
12
|
+
const candidates = [];
|
|
13
|
+
if (process.env.CLAUDE_PROJECT_DIR) {
|
|
14
|
+
candidates.push(process.env.CLAUDE_PROJECT_DIR);
|
|
15
|
+
}
|
|
16
|
+
let dir = process.cwd();
|
|
17
|
+
for (let i = 0; i < 12; i++) {
|
|
18
|
+
candidates.push(dir);
|
|
19
|
+
const parent = path.dirname(dir);
|
|
20
|
+
if (parent === dir) break;
|
|
21
|
+
dir = parent;
|
|
22
|
+
}
|
|
23
|
+
for (const base of candidates) {
|
|
24
|
+
const p = path.join(base, STATE_RELPATH);
|
|
25
|
+
if (fs.existsSync(p)) return p;
|
|
26
|
+
}
|
|
27
|
+
// Fall back to writing relative to CLAUDE_PROJECT_DIR or cwd (for setMode)
|
|
28
|
+
return path.join(process.env.CLAUDE_PROJECT_DIR || process.cwd(), STATE_RELPATH);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function normalizeMode(mode) {
|
|
32
|
+
if (typeof mode !== 'string') return null;
|
|
33
|
+
const normalized = mode.trim().toLowerCase();
|
|
34
|
+
return ['off', 'lite', 'full', 'ultra'].includes(normalized) ? normalized : null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function normalizePersistedMode(mode) {
|
|
38
|
+
if (typeof mode !== 'string') return null;
|
|
39
|
+
const normalized = mode.trim().toLowerCase();
|
|
40
|
+
return VALID_MODES.includes(normalized) ? normalized : null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getDefaultMode() {
|
|
44
|
+
const env = process.env.MONOLEAN_DEFAULT_MODE;
|
|
45
|
+
if (env && VALID_MODES.includes(env.toLowerCase())) return env.toLowerCase();
|
|
46
|
+
try {
|
|
47
|
+
const val = fs.readFileSync(findStateFile(), 'utf8').trim();
|
|
48
|
+
if (val && VALID_MODES.includes(val)) return val;
|
|
49
|
+
} catch { /* fall through */ }
|
|
50
|
+
return DEFAULT_MODE;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function setMode(mode) {
|
|
54
|
+
const f = findStateFile();
|
|
55
|
+
fs.mkdirSync(path.dirname(f), { recursive: true });
|
|
56
|
+
fs.writeFileSync(f, mode);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function readMode() {
|
|
60
|
+
try { return fs.readFileSync(findStateFile(), 'utf8').trim() || null; } catch { return null; }
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function clearMode() {
|
|
64
|
+
try { fs.unlinkSync(findStateFile()); } catch {}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function isDeactivationCommand(text) {
|
|
68
|
+
const t = String(text || '').trim().toLowerCase().replace(/[.!?\s]+$/, '');
|
|
69
|
+
return t === 'stop monolean' || t === 'normal mode';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
module.exports = {
|
|
73
|
+
VALID_MODES, DEFAULT_MODE,
|
|
74
|
+
normalizeMode, normalizePersistedMode,
|
|
75
|
+
getDefaultMode, setMode, readMode, clearMode, isDeactivationCommand,
|
|
76
|
+
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { DEFAULT_MODE, normalizeMode, normalizePersistedMode } = require('./monolean-config.cjs');
|
|
5
|
+
|
|
6
|
+
const INDEPENDENT_MODES = new Set(['review']);
|
|
7
|
+
|
|
8
|
+
// Resolve the SKILL.md path lazily, walking up from cwd if CLAUDE_PROJECT_DIR doesn't have it.
|
|
9
|
+
// Required for SubagentStart hooks where CLAUDE_PROJECT_DIR may differ from the parent project.
|
|
10
|
+
function findSkillPath() {
|
|
11
|
+
const candidates = [];
|
|
12
|
+
if (process.env.CLAUDE_PROJECT_DIR) {
|
|
13
|
+
candidates.push(process.env.CLAUDE_PROJECT_DIR);
|
|
14
|
+
}
|
|
15
|
+
// Walk up from cwd to find the project root containing the skill
|
|
16
|
+
let dir = process.cwd();
|
|
17
|
+
for (let i = 0; i < 12; i++) {
|
|
18
|
+
candidates.push(dir);
|
|
19
|
+
const parent = path.dirname(dir);
|
|
20
|
+
if (parent === dir) break;
|
|
21
|
+
dir = parent;
|
|
22
|
+
}
|
|
23
|
+
for (const base of candidates) {
|
|
24
|
+
const p = path.join(base, '.claude', 'skills', 'monolean', 'SKILL.md');
|
|
25
|
+
if (fs.existsSync(p)) return p;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function filterSkillBodyForMode(body, mode) {
|
|
31
|
+
const effectiveMode = normalizeMode(mode) || DEFAULT_MODE;
|
|
32
|
+
const withoutFrontmatter = String(body || '').replace(/^---[\s\S]*?---\s*/, '');
|
|
33
|
+
|
|
34
|
+
return withoutFrontmatter
|
|
35
|
+
.split(/\r?\n/)
|
|
36
|
+
.filter((line) => {
|
|
37
|
+
const tableLabel = line.match(/^\|\s*\*\*(.+?)\*\*\s*\|/);
|
|
38
|
+
if (tableLabel) {
|
|
39
|
+
const labelMode = normalizeMode(tableLabel[1].trim());
|
|
40
|
+
if (labelMode) return labelMode === effectiveMode;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const exampleLabel = line.match(/^-\s*([^:]+):\s*/);
|
|
44
|
+
if (exampleLabel) {
|
|
45
|
+
const labelMode = normalizeMode(exampleLabel[1].trim());
|
|
46
|
+
if (labelMode) return labelMode === effectiveMode;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return true;
|
|
50
|
+
})
|
|
51
|
+
.join('\n');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function getFallbackInstructions(mode) {
|
|
55
|
+
return 'MONOLEAN MODE ACTIVE — level: ' + mode + '\n\n' +
|
|
56
|
+
'You are a lazy senior developer. Lazy means efficient, not careless. The best code is the code never written.\n\n' +
|
|
57
|
+
'## Persistence\n\n' +
|
|
58
|
+
'ACTIVE EVERY RESPONSE. No drift back to over-building. Still active if unsure. Off only: "stop monolean" / "normal mode".\n\n' +
|
|
59
|
+
'Current level: **' + mode + '**. Switch: `/monolean lite|full|ultra`.\n\n' +
|
|
60
|
+
'## The ladder\n\n' +
|
|
61
|
+
'Before any code, stop at the first rung that holds (the ladder runs after you understand the problem, not instead of it — read the code it touches and trace the real flow first):\n' +
|
|
62
|
+
'1. Does this need to be built at all? (YAGNI)\n' +
|
|
63
|
+
'2. Does it already exist in this codebase? Reuse what is already here, do not re-write it.\n' +
|
|
64
|
+
'3. Does the standard library do this? Use it.\n' +
|
|
65
|
+
'4. Does a native platform feature cover it? Use it.\n' +
|
|
66
|
+
'5. Does an already-installed dependency solve it? Use it.\n' +
|
|
67
|
+
'6. Can this be one line? Make it one line.\n' +
|
|
68
|
+
'7. Only then: write the minimum code that works.\n\n' +
|
|
69
|
+
'Bug fix = root cause, not symptom: grep every caller of the function you touch and fix the shared function once.\n\n' +
|
|
70
|
+
'## Rules\n\n' +
|
|
71
|
+
'No abstractions that were not requested. No avoidable dependencies. No boilerplate nobody asked for. ' +
|
|
72
|
+
'Deletion over addition. Boring over clever. Fewest files possible. ' +
|
|
73
|
+
'Mark intentional simplifications with a `monolean:` comment — a shortcut with a known ceiling names the ceiling and the upgrade path.\n\n' +
|
|
74
|
+
'## Output\n\n' +
|
|
75
|
+
'Code first. Then at most three short lines: what was skipped, when to add it.\n\n' +
|
|
76
|
+
'## When NOT to be lean\n\n' +
|
|
77
|
+
'Never simplify away: input validation at trust boundaries, error handling that prevents data loss, ' +
|
|
78
|
+
'security measures, accessibility basics, anything the user explicitly asked to keep. ' +
|
|
79
|
+
'Lean code without its check is unfinished: non-trivial logic leaves ONE runnable check behind.\n\n' +
|
|
80
|
+
'## Boundaries\n\n' +
|
|
81
|
+
'Monolean governs what you build, not how you talk. "stop monolean" or "normal mode": revert. Level persists until changed or session end.';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function getMonoleanInstructions(mode) {
|
|
85
|
+
const configuredMode = normalizePersistedMode(mode) || DEFAULT_MODE;
|
|
86
|
+
|
|
87
|
+
if (INDEPENDENT_MODES.has(configuredMode)) {
|
|
88
|
+
return 'MONOLEAN MODE ACTIVE — level: ' + configuredMode + '. Behavior defined by /monolean-' + configuredMode + ' skill.';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const effectiveMode = normalizeMode(configuredMode) || DEFAULT_MODE;
|
|
92
|
+
|
|
93
|
+
const skillPath = findSkillPath();
|
|
94
|
+
if (skillPath) {
|
|
95
|
+
try {
|
|
96
|
+
return 'MONOLEAN MODE ACTIVE — level: ' + effectiveMode + '\n\n' +
|
|
97
|
+
filterSkillBodyForMode(fs.readFileSync(skillPath, 'utf8'), effectiveMode);
|
|
98
|
+
} catch (e) {
|
|
99
|
+
// fall through to hardcoded fallback
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return getFallbackInstructions(effectiveMode);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
module.exports = {
|
|
106
|
+
filterSkillBodyForMode,
|
|
107
|
+
getFallbackInstructions,
|
|
108
|
+
getMonoleanInstructions,
|
|
109
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { readMode } = require('./monolean-config.cjs');
|
|
3
|
+
const { getMonoleanInstructions } = require('./monolean-instructions.cjs');
|
|
4
|
+
|
|
5
|
+
const mode = readMode();
|
|
6
|
+
if (!mode || mode === 'off') process.exit(0);
|
|
7
|
+
|
|
8
|
+
const instructions = getMonoleanInstructions(mode);
|
|
9
|
+
process.stdout.write(instructions);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { VALID_MODES, setMode, clearMode, isDeactivationCommand } = require('./monolean-config.cjs');
|
|
3
|
+
|
|
4
|
+
let data = '';
|
|
5
|
+
process.stdin.on('data', d => data += d);
|
|
6
|
+
process.stdin.on('end', () => {
|
|
7
|
+
try {
|
|
8
|
+
const parsed = JSON.parse(data);
|
|
9
|
+
const prompt = String(parsed.prompt || '');
|
|
10
|
+
if (isDeactivationCommand(prompt)) { clearMode(); process.exit(0); }
|
|
11
|
+
const m = prompt.match(/^[/@$]monolean\s*(\w+)?/i);
|
|
12
|
+
if (!m) process.exit(0);
|
|
13
|
+
const requested = (m[1] || 'full').toLowerCase();
|
|
14
|
+
if (!VALID_MODES.includes(requested)) process.exit(0);
|
|
15
|
+
if (requested === 'off') clearMode();
|
|
16
|
+
else setMode(requested);
|
|
17
|
+
} catch { /* ignore parse errors */ }
|
|
18
|
+
});
|