memnant 0.1.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.
- package/LICENSE +21 -0
- package/README.md +101 -0
- package/dist/cli/ask.d.ts +9 -0
- package/dist/cli/ask.d.ts.map +1 -0
- package/dist/cli/ask.js +103 -0
- package/dist/cli/ask.js.map +1 -0
- package/dist/cli/check-copy.d.ts +8 -0
- package/dist/cli/check-copy.d.ts.map +1 -0
- package/dist/cli/check-copy.js +68 -0
- package/dist/cli/check-copy.js.map +1 -0
- package/dist/cli/check-design.d.ts +8 -0
- package/dist/cli/check-design.d.ts.map +1 -0
- package/dist/cli/check-design.js +100 -0
- package/dist/cli/check-design.js.map +1 -0
- package/dist/cli/default-action.d.ts +10 -0
- package/dist/cli/default-action.d.ts.map +1 -0
- package/dist/cli/default-action.js +94 -0
- package/dist/cli/default-action.js.map +1 -0
- package/dist/cli/export.d.ts +10 -0
- package/dist/cli/export.d.ts.map +1 -0
- package/dist/cli/export.js +109 -0
- package/dist/cli/export.js.map +1 -0
- package/dist/cli/index.d.ts +12 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +77 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +10 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +157 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/instructions.d.ts +12 -0
- package/dist/cli/instructions.d.ts.map +1 -0
- package/dist/cli/instructions.js +117 -0
- package/dist/cli/instructions.js.map +1 -0
- package/dist/cli/lint.d.ts +9 -0
- package/dist/cli/lint.d.ts.map +1 -0
- package/dist/cli/lint.js +131 -0
- package/dist/cli/lint.js.map +1 -0
- package/dist/cli/log.d.ts +10 -0
- package/dist/cli/log.d.ts.map +1 -0
- package/dist/cli/log.js +83 -0
- package/dist/cli/log.js.map +1 -0
- package/dist/cli/promote.d.ts +9 -0
- package/dist/cli/promote.d.ts.map +1 -0
- package/dist/cli/promote.js +70 -0
- package/dist/cli/promote.js.map +1 -0
- package/dist/cli/recall.d.ts +10 -0
- package/dist/cli/recall.d.ts.map +1 -0
- package/dist/cli/recall.js +98 -0
- package/dist/cli/recall.js.map +1 -0
- package/dist/cli/serve.d.ts +10 -0
- package/dist/cli/serve.d.ts.map +1 -0
- package/dist/cli/serve.js +17 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/cli/session.d.ts +10 -0
- package/dist/cli/session.d.ts.map +1 -0
- package/dist/cli/session.js +226 -0
- package/dist/cli/session.js.map +1 -0
- package/dist/cli/setup.d.ts +11 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +103 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/cli/snapshot.d.ts +9 -0
- package/dist/cli/snapshot.d.ts.map +1 -0
- package/dist/cli/snapshot.js +126 -0
- package/dist/cli/snapshot.js.map +1 -0
- package/dist/cli/specs.d.ts +8 -0
- package/dist/cli/specs.d.ts.map +1 -0
- package/dist/cli/specs.js +96 -0
- package/dist/cli/specs.js.map +1 -0
- package/dist/cli/status.d.ts +8 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +40 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/telegram.d.ts +8 -0
- package/dist/cli/telegram.d.ts.map +1 -0
- package/dist/cli/telegram.js +40 -0
- package/dist/cli/telegram.js.map +1 -0
- package/dist/cli/test-persona.d.ts +9 -0
- package/dist/cli/test-persona.d.ts.map +1 -0
- package/dist/cli/test-persona.js +176 -0
- package/dist/cli/test-persona.js.map +1 -0
- package/dist/config/defaults.d.ts +9 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +56 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/context/compile.d.ts +29 -0
- package/dist/context/compile.d.ts.map +1 -0
- package/dist/context/compile.js +415 -0
- package/dist/context/compile.js.map +1 -0
- package/dist/governor/copy-check.d.ts +24 -0
- package/dist/governor/copy-check.d.ts.map +1 -0
- package/dist/governor/copy-check.js +75 -0
- package/dist/governor/copy-check.js.map +1 -0
- package/dist/governor/design-check.d.ts +20 -0
- package/dist/governor/design-check.d.ts.map +1 -0
- package/dist/governor/design-check.js +40 -0
- package/dist/governor/design-check.js.map +1 -0
- package/dist/governor/specs.d.ts +58 -0
- package/dist/governor/specs.d.ts.map +1 -0
- package/dist/governor/specs.js +183 -0
- package/dist/governor/specs.js.map +1 -0
- package/dist/ledger/database.d.ts +12 -0
- package/dist/ledger/database.d.ts.map +1 -0
- package/dist/ledger/database.js +56 -0
- package/dist/ledger/database.js.map +1 -0
- package/dist/ledger/records.d.ts +19 -0
- package/dist/ledger/records.d.ts.map +1 -0
- package/dist/ledger/records.js +40 -0
- package/dist/ledger/records.js.map +1 -0
- package/dist/ledger/sessions.d.ts +15 -0
- package/dist/ledger/sessions.d.ts.map +1 -0
- package/dist/ledger/sessions.js +54 -0
- package/dist/ledger/sessions.js.map +1 -0
- package/dist/mcp/server.d.ts +9 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +295 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/orchestrator/context.d.ts +22 -0
- package/dist/orchestrator/context.d.ts.map +1 -0
- package/dist/orchestrator/context.js +142 -0
- package/dist/orchestrator/context.js.map +1 -0
- package/dist/orchestrator/providers.d.ts +17 -0
- package/dist/orchestrator/providers.d.ts.map +1 -0
- package/dist/orchestrator/providers.js +57 -0
- package/dist/orchestrator/providers.js.map +1 -0
- package/dist/orchestrator/router.d.ts +30 -0
- package/dist/orchestrator/router.d.ts.map +1 -0
- package/dist/orchestrator/router.js +83 -0
- package/dist/orchestrator/router.js.map +1 -0
- package/dist/snapshot/scanner.d.ts +63 -0
- package/dist/snapshot/scanner.d.ts.map +1 -0
- package/dist/snapshot/scanner.js +293 -0
- package/dist/snapshot/scanner.js.map +1 -0
- package/dist/telegram/bot.d.ts +14 -0
- package/dist/telegram/bot.d.ts.map +1 -0
- package/dist/telegram/bot.js +139 -0
- package/dist/telegram/bot.js.map +1 -0
- package/dist/types.d.ts +99 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/dist/vector/embeddings.d.ts +11 -0
- package/dist/vector/embeddings.d.ts.map +1 -0
- package/dist/vector/embeddings.js +30 -0
- package/dist/vector/embeddings.js.map +1 -0
- package/dist/vector/search.d.ts +26 -0
- package/dist/vector/search.d.ts.map +1 -0
- package/dist/vector/search.js +51 -0
- package/dist/vector/search.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 peureka
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# memnant
|
|
2
|
+
|
|
3
|
+
Your agent forgets everything between sessions. memnant is the structured ledger that survives.
|
|
4
|
+
|
|
5
|
+
Context windows die. Conversations end. Three weeks later you're re-explaining decisions your agent already made with you. memnant gives your agent a typed, searchable, staleness-aware decision ledger — and it already knows how to use it.
|
|
6
|
+
|
|
7
|
+
**[memnant.vercel.app](https://memnant.vercel.app)**
|
|
8
|
+
|
|
9
|
+
## Get started
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
cd your-project
|
|
13
|
+
npx memnant
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
That's it. First run walks you through setup — project name, agent config, starter specs. Every run after that starts a session and prints compiled context. Open your agent, start building.
|
|
17
|
+
|
|
18
|
+
## How it works
|
|
19
|
+
|
|
20
|
+
1. **Run one command.** `npx memnant` in any project. It auto-detects what to do: first time → guided setup, no session → start one, in session → show status.
|
|
21
|
+
|
|
22
|
+
2. **Open your agent.** memnant registers as an MCP server. Your agent gets 7 tools — recall, log, session context, session close, copy check, design check, status. It already knows when to call them.
|
|
23
|
+
|
|
24
|
+
3. **Build.** Your agent checks prior decisions before making new ones. Logs what it decides. Catches stale records when the codebase drifts. Closes the session with a summary when you're done — through conversation, not CLI.
|
|
25
|
+
|
|
26
|
+
## What the agent gets
|
|
27
|
+
|
|
28
|
+
### Decision Ledger
|
|
29
|
+
Append-only records with vector embeddings. Decisions, framework fixes, spec snapshots — all semantically searchable. The agent calls `memnant_recall` and finds what it needs.
|
|
30
|
+
|
|
31
|
+
### Session Lifecycle
|
|
32
|
+
Compiled context at session start: last session's log, open TODOs, relevant decisions, framework fixes, spec constraints. Session close happens through the agent via `memnant_session_close`. No CLI needed.
|
|
33
|
+
|
|
34
|
+
### Staleness Detection
|
|
35
|
+
Codebase snapshots track file hashes. When a file changes after a decision was logged about it, that record is flagged `[stale]` in recall and session context.
|
|
36
|
+
|
|
37
|
+
### Spec Governor
|
|
38
|
+
Copy audits catch banned phrases. Design system checks catch banned components. The agent validates via MCP tools. Also runs in CI with `memnant lint`.
|
|
39
|
+
|
|
40
|
+
### Model Orchestrator
|
|
41
|
+
Three tiers: triage (Haiku), analysis (Sonnet), build (Opus). Each gets tier-appropriate context.
|
|
42
|
+
|
|
43
|
+
## MCP Tools
|
|
44
|
+
|
|
45
|
+
memnant exposes 7 tools via MCP (stdio transport):
|
|
46
|
+
|
|
47
|
+
| Tool | Description |
|
|
48
|
+
|------|-------------|
|
|
49
|
+
| `memnant_recall` | Semantic search across all records |
|
|
50
|
+
| `memnant_log` | Log a decision, framework fix, or session log |
|
|
51
|
+
| `memnant_session_context` | Get compiled session context |
|
|
52
|
+
| `memnant_session_close` | Close the active session with a summary |
|
|
53
|
+
| `memnant_status` | Project status |
|
|
54
|
+
| `memnant_check_copy` | Copy audit against spec |
|
|
55
|
+
| `memnant_check_design` | Design system validation |
|
|
56
|
+
|
|
57
|
+
MCP is auto-configured by `npx memnant` on first run. Works with Claude Code, Codex, and any MCP-compatible agent.
|
|
58
|
+
|
|
59
|
+
## Advanced CLI
|
|
60
|
+
|
|
61
|
+
All commands are still available for scripts, CI, and power users:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
memnant init memnant session start memnant check-copy
|
|
65
|
+
memnant setup claude-code memnant session close memnant check-design
|
|
66
|
+
memnant setup codex memnant session status memnant test-persona
|
|
67
|
+
memnant log memnant snapshot memnant lint
|
|
68
|
+
memnant recall memnant export memnant serve
|
|
69
|
+
memnant ask memnant specs memnant instructions
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Stack
|
|
73
|
+
|
|
74
|
+
- TypeScript, Node.js (ESM)
|
|
75
|
+
- SQLite via node-sqlite3-wasm
|
|
76
|
+
- Local vector embeddings via @xenova/transformers (all-MiniLM-L6-v2)
|
|
77
|
+
- CLI via Commander.js
|
|
78
|
+
- MCP server via @modelcontextprotocol/sdk
|
|
79
|
+
- 192 tests via vitest
|
|
80
|
+
|
|
81
|
+
## Development
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
git clone https://github.com/peureka/memnant.git
|
|
85
|
+
cd memnant
|
|
86
|
+
npm install
|
|
87
|
+
npm run build
|
|
88
|
+
npm test
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Documentation
|
|
92
|
+
|
|
93
|
+
- [`docs/PRODUCT.md`](docs/PRODUCT.md) — What memnant is, what it isn't, why it's different
|
|
94
|
+
- [`docs/SPEC.md`](docs/SPEC.md) — Data model and system behaviours
|
|
95
|
+
- [`docs/PLAN.md`](docs/PLAN.md) — Build plan with epics, stories, and acceptance criteria
|
|
96
|
+
- [`docs/PROJECT_INSTRUCTIONS.md`](docs/PROJECT_INSTRUCTIONS.md) — Decision framework
|
|
97
|
+
- [`docs/PERSONA_KAI.md`](docs/PERSONA_KAI.md) — Primary persona
|
|
98
|
+
|
|
99
|
+
## License
|
|
100
|
+
|
|
101
|
+
MIT
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant ask — Route a task to the appropriate model tier.
|
|
3
|
+
*
|
|
4
|
+
* Story 4.1: Intent classification, tier routing, context injection,
|
|
5
|
+
* and model provider integration.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
export declare function registerAskCommand(program: Command): void;
|
|
9
|
+
//# sourceMappingURL=ask.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../src/cli/ask.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqGzD"}
|
package/dist/cli/ask.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant ask — Route a task to the appropriate model tier.
|
|
3
|
+
*
|
|
4
|
+
* Story 4.1: Intent classification, tier routing, context injection,
|
|
5
|
+
* and model provider integration.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readFileSync } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import yaml from 'js-yaml';
|
|
10
|
+
import { openDatabase } from '../ledger/database.js';
|
|
11
|
+
import { insertRecord } from '../ledger/records.js';
|
|
12
|
+
import { generateEmbedding, serializeEmbedding } from '../vector/embeddings.js';
|
|
13
|
+
import { getActiveSession } from '../ledger/sessions.js';
|
|
14
|
+
import { classifyIntent, getApiKeyEnvVar } from '../orchestrator/router.js';
|
|
15
|
+
import { callModel } from '../orchestrator/providers.js';
|
|
16
|
+
import { buildTierContext } from '../orchestrator/context.js';
|
|
17
|
+
export function registerAskCommand(program) {
|
|
18
|
+
program
|
|
19
|
+
.command('ask')
|
|
20
|
+
.description('Send a task to memnant for routing and execution')
|
|
21
|
+
.argument('<message>', 'The task or question to route')
|
|
22
|
+
.option('--tier <n>', 'Override automatic tier routing (1, 2, or 3)')
|
|
23
|
+
.option('--dry-run', 'Show routing decision and context without calling the model')
|
|
24
|
+
.action(async (message, opts) => {
|
|
25
|
+
const cwd = process.cwd();
|
|
26
|
+
const configPath = join(cwd, 'memnant.yaml');
|
|
27
|
+
if (!existsSync(configPath)) {
|
|
28
|
+
console.error('No memnant project found. Run `memnant init` first.');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
const config = yaml.load(readFileSync(configPath, 'utf-8'));
|
|
32
|
+
const dbPath = join(cwd, config.memory.db_path);
|
|
33
|
+
if (!existsSync(dbPath)) {
|
|
34
|
+
console.error(`Ledger database not found at ${config.memory.db_path}. Run \`memnant init\` to recreate.`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
// Determine tier
|
|
38
|
+
let tier;
|
|
39
|
+
let routingReason;
|
|
40
|
+
if (opts.tier) {
|
|
41
|
+
const n = parseInt(opts.tier, 10);
|
|
42
|
+
if (![1, 2, 3].includes(n)) {
|
|
43
|
+
console.error(`Invalid tier '${opts.tier}'. Must be 1, 2, or 3.`);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
tier = n;
|
|
47
|
+
routingReason = 'manual override';
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const routing = classifyIntent(message);
|
|
51
|
+
tier = routing.tier;
|
|
52
|
+
routingReason = routing.reason;
|
|
53
|
+
}
|
|
54
|
+
// Get tier config
|
|
55
|
+
const tierNames = { 1: 'triage', 2: 'analysis', 3: 'build' };
|
|
56
|
+
const tierName = tierNames[tier];
|
|
57
|
+
const tierConfig = config.orchestrator.tiers[tierName];
|
|
58
|
+
// Check API key
|
|
59
|
+
const envVar = getApiKeyEnvVar(tierConfig.provider);
|
|
60
|
+
if (!process.env[envVar]) {
|
|
61
|
+
console.error(`Set ${envVar} to use Tier ${tier}.`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
const db = openDatabase(dbPath);
|
|
65
|
+
try {
|
|
66
|
+
// Build context
|
|
67
|
+
const docsPath = join(cwd, config.governor.docs_path);
|
|
68
|
+
const ctx = await buildTierContext(db, config, tier, message, docsPath, cwd);
|
|
69
|
+
// Dry run — show routing and context
|
|
70
|
+
if (opts.dryRun) {
|
|
71
|
+
console.log(`Tier: ${tier} (${tierName})`);
|
|
72
|
+
console.log(`Reason: ${routingReason}`);
|
|
73
|
+
console.log(`Model: ${tierConfig.provider}/${tierConfig.model}`);
|
|
74
|
+
console.log(`Context: ~${ctx.tokenEstimate} tokens, ${ctx.recordCount} records`);
|
|
75
|
+
console.log('');
|
|
76
|
+
console.log(ctx.systemPrompt);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// Call model
|
|
80
|
+
const response = await callModel(tierConfig, ctx.systemPrompt, message);
|
|
81
|
+
// Log orchestrator_task record
|
|
82
|
+
const taskSummary = `Task: ${message}\nTier: ${tier} (${tierName})\nModel: ${tierConfig.model}\nResponse: ${response.text.slice(0, 500)}`;
|
|
83
|
+
const taskEmbedding = await generateEmbedding(taskSummary);
|
|
84
|
+
const taskEmbeddingBuffer = serializeEmbedding(taskEmbedding);
|
|
85
|
+
const activeSession = getActiveSession(db, config.project.id);
|
|
86
|
+
insertRecord(db, {
|
|
87
|
+
projectId: config.project.id,
|
|
88
|
+
type: 'orchestrator_task',
|
|
89
|
+
contentText: taskSummary,
|
|
90
|
+
embedding: taskEmbeddingBuffer,
|
|
91
|
+
sourceSession: activeSession?.id ?? null,
|
|
92
|
+
});
|
|
93
|
+
// Output response
|
|
94
|
+
console.log(response.text);
|
|
95
|
+
console.log('');
|
|
96
|
+
console.log(`[Tier ${tier}: ${tierConfig.model}, ~${response.input_tokens + response.output_tokens} tokens, ${ctx.recordCount} records injected]`);
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
db.close();
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=ask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../../src/cli/ask.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant check-copy — Copy audit check command.
|
|
3
|
+
*
|
|
4
|
+
* Story 5.2: Checks text against copy audit rules.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
export declare function registerCheckCopyCommand(program: Command): void;
|
|
8
|
+
//# sourceMappingURL=check-copy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-copy.d.ts","sourceRoot":"","sources":["../../src/cli/check-copy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6D/D"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant check-copy — Copy audit check command.
|
|
3
|
+
*
|
|
4
|
+
* Story 5.2: Checks text against copy audit rules.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, readFileSync } from 'fs';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
import yaml from 'js-yaml';
|
|
9
|
+
import { checkCopy } from '../governor/copy-check.js';
|
|
10
|
+
import { scanSpecs } from '../governor/specs.js';
|
|
11
|
+
export function registerCheckCopyCommand(program) {
|
|
12
|
+
program
|
|
13
|
+
.command('check-copy')
|
|
14
|
+
.description('Check text against the copy audit spec')
|
|
15
|
+
.argument('[text]', 'Text to check (or use --file)')
|
|
16
|
+
.option('--file <path>', 'Check an entire file')
|
|
17
|
+
.action((text, opts) => {
|
|
18
|
+
const cwd = process.cwd();
|
|
19
|
+
const configPath = join(cwd, 'memnant.yaml');
|
|
20
|
+
if (!existsSync(configPath)) {
|
|
21
|
+
console.error('No memnant project found. Run `memnant init` first.');
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
const config = yaml.load(readFileSync(configPath, 'utf-8'));
|
|
25
|
+
const docsPath = join(cwd, config.governor.docs_path);
|
|
26
|
+
// Check if copy audit spec exists
|
|
27
|
+
const specs = scanSpecs(docsPath);
|
|
28
|
+
const copySpec = specs.find((s) => s.frontmatter.type === 'copy_audit');
|
|
29
|
+
if (!copySpec) {
|
|
30
|
+
console.log(`No copy audit spec found in ${config.governor.docs_path}. Create one with type: copy_audit frontmatter.`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
// Get text to check
|
|
34
|
+
let content;
|
|
35
|
+
if (opts.file) {
|
|
36
|
+
const filePath = join(cwd, opts.file);
|
|
37
|
+
if (!existsSync(filePath)) {
|
|
38
|
+
console.error(`File not found: ${opts.file}`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
content = readFileSync(filePath, 'utf-8');
|
|
42
|
+
}
|
|
43
|
+
else if (text) {
|
|
44
|
+
content = text;
|
|
45
|
+
}
|
|
46
|
+
else if (!process.stdin.isTTY) {
|
|
47
|
+
content = readFileSync(0, 'utf-8');
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
console.error('Provide text as an argument, via --file, or pipe from stdin.');
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
const result = checkCopy(content, docsPath);
|
|
54
|
+
if (result.violations.length === 0) {
|
|
55
|
+
console.log('No copy violations found.');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
for (const v of result.violations) {
|
|
59
|
+
const lineInfo = v.line ? `:${v.line}` : '';
|
|
60
|
+
const prefix = opts.file ? `${opts.file}${lineInfo} ` : '';
|
|
61
|
+
console.log(`${prefix}${v.message}`);
|
|
62
|
+
}
|
|
63
|
+
if (result.hasBanned) {
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=check-copy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-copy.js","sourceRoot":"","sources":["../../src/cli/check-copy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGjD,MAAM,UAAU,wBAAwB,CAAC,OAAgB;IACvD,OAAO;SACJ,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,CAAC,wCAAwC,CAAC;SACrD,QAAQ,CAAC,QAAQ,EAAE,+BAA+B,CAAC;SACnD,MAAM,CAAC,eAAe,EAAE,sBAAsB,CAAC;SAC/C,MAAM,CAAC,CAAC,IAAwB,EAAE,IAAuB,EAAE,EAAE;QAC5D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAE7C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;YACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAkB,CAAC;QAC7E,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAEtD,kCAAkC;QAClC,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;QACxE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,+BAA+B,MAAM,CAAC,QAAQ,CAAC,SAAS,iDAAiD,CAAC,CAAC;YACvH,OAAO;QACT,CAAC;QAED,oBAAoB;QACpB,IAAI,OAAe,CAAC;QACpB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1B,OAAO,CAAC,KAAK,CAAC,mBAAmB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC5C,CAAC;aAAM,IAAI,IAAI,EAAE,CAAC;YAChB,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;aAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YAChC,OAAO,GAAG,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC;YAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAE5C,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YAClC,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,CAAC;QAED,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant check-design — Design system validation command.
|
|
3
|
+
*
|
|
4
|
+
* Story 5.3: Scans source files for banned components from the design system spec.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
export declare function registerCheckDesignCommand(program: Command): void;
|
|
8
|
+
//# sourceMappingURL=check-design.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-design.d.ts","sourceRoot":"","sources":["../../src/cli/check-design.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2DjE"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant check-design — Design system validation command.
|
|
3
|
+
*
|
|
4
|
+
* Story 5.3: Scans source files for banned components from the design system spec.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'fs';
|
|
7
|
+
import { join, relative } from 'path';
|
|
8
|
+
import yaml from 'js-yaml';
|
|
9
|
+
import { checkDesign } from '../governor/design-check.js';
|
|
10
|
+
import { scanSpecs } from '../governor/specs.js';
|
|
11
|
+
export function registerCheckDesignCommand(program) {
|
|
12
|
+
program
|
|
13
|
+
.command('check-design')
|
|
14
|
+
.description('Check source files for banned components from the design system spec')
|
|
15
|
+
.argument('<path>', 'File or directory to check')
|
|
16
|
+
.action((targetPath) => {
|
|
17
|
+
const cwd = process.cwd();
|
|
18
|
+
const configPath = join(cwd, 'memnant.yaml');
|
|
19
|
+
if (!existsSync(configPath)) {
|
|
20
|
+
console.error('No memnant project found. Run `memnant init` first.');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
const config = yaml.load(readFileSync(configPath, 'utf-8'));
|
|
24
|
+
const docsPath = join(cwd, config.governor.docs_path);
|
|
25
|
+
// Check if design system spec exists
|
|
26
|
+
const specs = scanSpecs(docsPath);
|
|
27
|
+
const designSpec = specs.find((s) => s.frontmatter.type === 'design_system');
|
|
28
|
+
if (!designSpec) {
|
|
29
|
+
console.log(`No design system spec found in ${config.governor.docs_path}. Create one with type: design_system frontmatter.`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const absPath = join(cwd, targetPath);
|
|
33
|
+
if (!existsSync(absPath)) {
|
|
34
|
+
console.error(`Path not found: ${targetPath}`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
const allViolations = [];
|
|
38
|
+
const stat = statSync(absPath);
|
|
39
|
+
if (stat.isFile()) {
|
|
40
|
+
const code = readFileSync(absPath, 'utf-8');
|
|
41
|
+
const result = checkDesign(code, targetPath, docsPath);
|
|
42
|
+
allViolations.push(...result.violations);
|
|
43
|
+
}
|
|
44
|
+
else if (stat.isDirectory()) {
|
|
45
|
+
const files = collectSourceFiles(absPath);
|
|
46
|
+
for (const file of files) {
|
|
47
|
+
const relPath = relative(cwd, file);
|
|
48
|
+
const code = readFileSync(file, 'utf-8');
|
|
49
|
+
const result = checkDesign(code, relPath, docsPath);
|
|
50
|
+
allViolations.push(...result.violations);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (allViolations.length === 0) {
|
|
54
|
+
console.log('No design system violations found.');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
for (const v of allViolations) {
|
|
58
|
+
console.log(`${v.file}:${v.line} ${v.message}`);
|
|
59
|
+
}
|
|
60
|
+
process.exit(1);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
const SOURCE_EXTENSIONS = new Set([
|
|
64
|
+
'.ts', '.tsx', '.js', '.jsx', '.vue', '.svelte',
|
|
65
|
+
'.html', '.css', '.scss',
|
|
66
|
+
]);
|
|
67
|
+
function collectSourceFiles(dir) {
|
|
68
|
+
const results = [];
|
|
69
|
+
const skipDirs = new Set(['node_modules', '.git', '.memnant', 'dist', '.next']);
|
|
70
|
+
let entries;
|
|
71
|
+
try {
|
|
72
|
+
entries = readdirSync(dir);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return results;
|
|
76
|
+
}
|
|
77
|
+
for (const entry of entries) {
|
|
78
|
+
if (skipDirs.has(entry))
|
|
79
|
+
continue;
|
|
80
|
+
const absPath = join(dir, entry);
|
|
81
|
+
let stat;
|
|
82
|
+
try {
|
|
83
|
+
stat = statSync(absPath);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (stat.isDirectory()) {
|
|
89
|
+
results.push(...collectSourceFiles(absPath));
|
|
90
|
+
}
|
|
91
|
+
else if (stat.isFile()) {
|
|
92
|
+
const ext = entry.slice(entry.lastIndexOf('.'));
|
|
93
|
+
if (SOURCE_EXTENSIONS.has(ext)) {
|
|
94
|
+
results.push(absPath);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return results;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=check-design.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-design.js","sourceRoot":"","sources":["../../src/cli/check-design.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant default action — State detection and routing.
|
|
3
|
+
*
|
|
4
|
+
* Story 6.1: When `memnant` is invoked with no subcommand, detect state and route:
|
|
5
|
+
* 1. No memnant.yaml → run interactive init
|
|
6
|
+
* 2. memnant.yaml exists, no active session → start session + print context
|
|
7
|
+
* 3. Active session exists → show session status
|
|
8
|
+
*/
|
|
9
|
+
export declare function defaultAction(): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=default-action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-action.d.ts","sourceRoot":"","sources":["../../src/cli/default-action.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CA6EnD"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant default action — State detection and routing.
|
|
3
|
+
*
|
|
4
|
+
* Story 6.1: When `memnant` is invoked with no subcommand, detect state and route:
|
|
5
|
+
* 1. No memnant.yaml → run interactive init
|
|
6
|
+
* 2. memnant.yaml exists, no active session → start session + print context
|
|
7
|
+
* 3. Active session exists → show session status
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readFileSync } from 'fs';
|
|
10
|
+
import { join } from 'path';
|
|
11
|
+
import yaml from 'js-yaml';
|
|
12
|
+
import { openDatabase } from '../ledger/database.js';
|
|
13
|
+
import { createSession, getActiveSession, getSessionRecordCounts } from '../ledger/sessions.js';
|
|
14
|
+
import { compileContext, formatContextAsMarkdown } from '../context/compile.js';
|
|
15
|
+
import { getLastSnapshotDate } from '../snapshot/scanner.js';
|
|
16
|
+
export async function defaultAction() {
|
|
17
|
+
const cwd = process.cwd();
|
|
18
|
+
const configPath = join(cwd, 'memnant.yaml');
|
|
19
|
+
// State 1: Not initialised → run init
|
|
20
|
+
if (!existsSync(configPath)) {
|
|
21
|
+
// Import init module and invoke directly
|
|
22
|
+
const initModule = await import('./init.js');
|
|
23
|
+
// Trigger init via registered command by re-parsing with 'init' arg
|
|
24
|
+
const { Command } = await import('commander');
|
|
25
|
+
const tempProgram = new Command();
|
|
26
|
+
tempProgram.exitOverride(); // Don't call process.exit
|
|
27
|
+
initModule.registerInitCommand(tempProgram);
|
|
28
|
+
await tempProgram.parseAsync(['init'], { from: 'user' });
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const config = yaml.load(readFileSync(configPath, 'utf-8'));
|
|
32
|
+
const dbPath = join(cwd, config.memory.db_path);
|
|
33
|
+
if (!existsSync(dbPath)) {
|
|
34
|
+
console.error(`Ledger database not found at ${config.memory.db_path}. Run \`memnant init\` to recreate.`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
const db = openDatabase(dbPath);
|
|
38
|
+
try {
|
|
39
|
+
const active = getActiveSession(db, config.project.id);
|
|
40
|
+
if (active) {
|
|
41
|
+
// State 3: Active session → show status
|
|
42
|
+
const duration = formatDuration(new Date(active.started_at), new Date());
|
|
43
|
+
const counts = getSessionRecordCounts(db, active.id);
|
|
44
|
+
const total = Object.values(counts).reduce((a, b) => a + b, 0);
|
|
45
|
+
console.log(`Session: ${active.id.slice(0, 8)}`);
|
|
46
|
+
console.log(`Started: ${active.started_at.slice(0, 19).replace('T', ' ')}`);
|
|
47
|
+
console.log(`Duration: ${duration}`);
|
|
48
|
+
if (active.epic) {
|
|
49
|
+
console.log(`Epic: ${active.epic}`);
|
|
50
|
+
}
|
|
51
|
+
console.log(`Records: ${total}`);
|
|
52
|
+
if (total > 0) {
|
|
53
|
+
for (const [type, count] of Object.entries(counts)) {
|
|
54
|
+
console.log(` ${type}: ${count}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// State 2: No active session → start session + print context
|
|
60
|
+
const docsPath = join(cwd, config.governor.docs_path);
|
|
61
|
+
const ctx = compileContext(db, { docsPath, projectRoot: cwd });
|
|
62
|
+
// Snapshot age reminder
|
|
63
|
+
if (config.memory.snapshot_interval === 'monthly') {
|
|
64
|
+
const lastDate = getLastSnapshotDate(db);
|
|
65
|
+
if (lastDate) {
|
|
66
|
+
const daysSince = Math.floor((Date.now() - new Date(lastDate).getTime()) / (1000 * 60 * 60 * 24));
|
|
67
|
+
if (daysSince > 30) {
|
|
68
|
+
ctx.warnings.push(`Last codebase snapshot is ${daysSince} days old. Run \`memnant snapshot\` to update staleness tracking.`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const session = createSession(db, config.project.id);
|
|
73
|
+
process.stderr.write(`Session ${session.id.slice(0, 8)} started.\n`);
|
|
74
|
+
console.log(formatContextAsMarkdown(ctx));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
db.close();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function formatDuration(start, end) {
|
|
82
|
+
const ms = end.getTime() - start.getTime();
|
|
83
|
+
const seconds = Math.floor(ms / 1000);
|
|
84
|
+
const minutes = Math.floor(seconds / 60);
|
|
85
|
+
const hours = Math.floor(minutes / 60);
|
|
86
|
+
if (hours > 0) {
|
|
87
|
+
return `${hours}h ${minutes % 60}m`;
|
|
88
|
+
}
|
|
89
|
+
if (minutes > 0) {
|
|
90
|
+
return `${minutes}m ${seconds % 60}s`;
|
|
91
|
+
}
|
|
92
|
+
return `${seconds}s`;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=default-action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-action.js","sourceRoot":"","sources":["../../src/cli/default-action.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant export — Export the ledger to portable formats.
|
|
3
|
+
*
|
|
4
|
+
* Story 1.5: Exports all records as markdown (one file per record, organised
|
|
5
|
+
* by type subdirectory) or as a single JSON file. Supports --since date filtering.
|
|
6
|
+
* Export is a full snapshot — previous files are overwritten.
|
|
7
|
+
*/
|
|
8
|
+
import { Command } from 'commander';
|
|
9
|
+
export declare function registerExportCommand(program: Command): void;
|
|
10
|
+
//# sourceMappingURL=export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/cli/export.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyBpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoE5D"}
|