@ag-eco/agentplate-cli 0.13.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 +462 -0
- package/agents/ap-co-creation.md +90 -0
- package/agents/builder.md +144 -0
- package/agents/coordinator.md +377 -0
- package/agents/lead.md +435 -0
- package/agents/merger.md +164 -0
- package/agents/monitor.md +214 -0
- package/agents/orchestrator.md +239 -0
- package/agents/reviewer.md +140 -0
- package/agents/scout.md +125 -0
- package/agents/supervisor.md +427 -0
- package/package.json +66 -0
- package/src/agents/capabilities.test.ts +85 -0
- package/src/agents/capabilities.ts +125 -0
- package/src/agents/checkpoint.test.ts +88 -0
- package/src/agents/checkpoint.ts +101 -0
- package/src/agents/copilot-hooks-deployer.test.ts +162 -0
- package/src/agents/copilot-hooks-deployer.ts +93 -0
- package/src/agents/guard-rules.test.ts +372 -0
- package/src/agents/guard-rules.ts +97 -0
- package/src/agents/headless-mail-injector.test.ts +709 -0
- package/src/agents/headless-mail-injector.ts +377 -0
- package/src/agents/headless-prompt.test.ts +102 -0
- package/src/agents/headless-prompt.ts +68 -0
- package/src/agents/hooks-deployer.test.ts +3119 -0
- package/src/agents/hooks-deployer.ts +804 -0
- package/src/agents/identity.test.ts +604 -0
- package/src/agents/identity.ts +384 -0
- package/src/agents/lifecycle.test.ts +196 -0
- package/src/agents/lifecycle.ts +183 -0
- package/src/agents/mail-poll-detect.test.ts +153 -0
- package/src/agents/mail-poll-detect.ts +73 -0
- package/src/agents/manifest.test.ts +1026 -0
- package/src/agents/manifest.ts +376 -0
- package/src/agents/overlay.test.ts +1058 -0
- package/src/agents/overlay.ts +490 -0
- package/src/agents/scope-detect.test.ts +190 -0
- package/src/agents/scope-detect.ts +146 -0
- package/src/agents/turn-lock.test.ts +181 -0
- package/src/agents/turn-lock.ts +235 -0
- package/src/agents/turn-runner-dispatch.test.ts +182 -0
- package/src/agents/turn-runner-dispatch.ts +105 -0
- package/src/agents/turn-runner.test.ts +2312 -0
- package/src/agents/turn-runner.ts +1383 -0
- package/src/beads/client.test.ts +217 -0
- package/src/beads/client.ts +230 -0
- package/src/beads/molecules.test.ts +338 -0
- package/src/beads/molecules.ts +198 -0
- package/src/commands/agents.test.ts +328 -0
- package/src/commands/agents.ts +299 -0
- package/src/commands/clean.test.ts +797 -0
- package/src/commands/clean.ts +791 -0
- package/src/commands/completions.test.ts +348 -0
- package/src/commands/completions.ts +981 -0
- package/src/commands/coordinator.test.ts +2975 -0
- package/src/commands/coordinator.ts +1841 -0
- package/src/commands/costs.test.ts +1183 -0
- package/src/commands/costs.ts +599 -0
- package/src/commands/dashboard.test.ts +954 -0
- package/src/commands/dashboard.ts +1212 -0
- package/src/commands/discover.test.ts +288 -0
- package/src/commands/discover.ts +202 -0
- package/src/commands/doctor.test.ts +303 -0
- package/src/commands/doctor.ts +311 -0
- package/src/commands/ecosystem.test.ts +226 -0
- package/src/commands/ecosystem.ts +248 -0
- package/src/commands/errors.test.ts +654 -0
- package/src/commands/errors.ts +197 -0
- package/src/commands/feed.test.ts +709 -0
- package/src/commands/feed.ts +260 -0
- package/src/commands/group.test.ts +475 -0
- package/src/commands/group.ts +546 -0
- package/src/commands/hooks.test.ts +458 -0
- package/src/commands/hooks.ts +263 -0
- package/src/commands/init.test.ts +1011 -0
- package/src/commands/init.ts +967 -0
- package/src/commands/inspect.test.ts +1239 -0
- package/src/commands/inspect.ts +648 -0
- package/src/commands/log.test.ts +1913 -0
- package/src/commands/log.ts +958 -0
- package/src/commands/logs.test.ts +801 -0
- package/src/commands/logs.ts +483 -0
- package/src/commands/mail.test.ts +1501 -0
- package/src/commands/mail.ts +848 -0
- package/src/commands/merge.test.ts +864 -0
- package/src/commands/merge.ts +381 -0
- package/src/commands/metrics.test.ts +458 -0
- package/src/commands/metrics.ts +129 -0
- package/src/commands/monitor.test.ts +191 -0
- package/src/commands/monitor.ts +409 -0
- package/src/commands/nudge.test.ts +579 -0
- package/src/commands/nudge.ts +646 -0
- package/src/commands/orchestrator.ts +42 -0
- package/src/commands/prime.test.ts +612 -0
- package/src/commands/prime.ts +359 -0
- package/src/commands/replay.test.ts +757 -0
- package/src/commands/replay.ts +231 -0
- package/src/commands/run.test.ts +469 -0
- package/src/commands/run.ts +353 -0
- package/src/commands/serve/agent-actions.test.ts +210 -0
- package/src/commands/serve/agent-actions.ts +192 -0
- package/src/commands/serve/build.test.ts +202 -0
- package/src/commands/serve/build.ts +206 -0
- package/src/commands/serve/coordinator-actions.test.ts +339 -0
- package/src/commands/serve/coordinator-actions.ts +410 -0
- package/src/commands/serve/dev.test.ts +168 -0
- package/src/commands/serve/dev.ts +117 -0
- package/src/commands/serve/mail-actions.test.ts +312 -0
- package/src/commands/serve/mail-actions.ts +167 -0
- package/src/commands/serve/rest.test.ts +1680 -0
- package/src/commands/serve/rest.ts +1130 -0
- package/src/commands/serve/static.ts +51 -0
- package/src/commands/serve/ws.test.ts +361 -0
- package/src/commands/serve/ws.ts +332 -0
- package/src/commands/serve.test.ts +459 -0
- package/src/commands/serve.ts +654 -0
- package/src/commands/sling.test.ts +1583 -0
- package/src/commands/sling.ts +1351 -0
- package/src/commands/spec.test.ts +179 -0
- package/src/commands/spec.ts +105 -0
- package/src/commands/status.test.ts +614 -0
- package/src/commands/status.ts +403 -0
- package/src/commands/stop.test.ts +964 -0
- package/src/commands/stop.ts +319 -0
- package/src/commands/supervisor.test.ts +185 -0
- package/src/commands/supervisor.ts +537 -0
- package/src/commands/trace.test.ts +762 -0
- package/src/commands/trace.ts +205 -0
- package/src/commands/update.test.ts +466 -0
- package/src/commands/update.ts +263 -0
- package/src/commands/upgrade.test.ts +48 -0
- package/src/commands/upgrade.ts +240 -0
- package/src/commands/watch.test.ts +257 -0
- package/src/commands/watch.ts +308 -0
- package/src/commands/worktree.test.ts +1297 -0
- package/src/commands/worktree.ts +451 -0
- package/src/config.test.ts +1535 -0
- package/src/config.ts +1064 -0
- package/src/doctor/agents.test.ts +523 -0
- package/src/doctor/agents.ts +399 -0
- package/src/doctor/config-check.test.ts +191 -0
- package/src/doctor/config-check.ts +183 -0
- package/src/doctor/consistency.test.ts +807 -0
- package/src/doctor/consistency.ts +347 -0
- package/src/doctor/databases.test.ts +350 -0
- package/src/doctor/databases.ts +243 -0
- package/src/doctor/dependencies.test.ts +296 -0
- package/src/doctor/dependencies.ts +272 -0
- package/src/doctor/ecosystem.test.ts +308 -0
- package/src/doctor/ecosystem.ts +156 -0
- package/src/doctor/logs.test.ts +253 -0
- package/src/doctor/logs.ts +295 -0
- package/src/doctor/merge-queue.test.ts +315 -0
- package/src/doctor/merge-queue.ts +167 -0
- package/src/doctor/providers.test.ts +409 -0
- package/src/doctor/providers.ts +250 -0
- package/src/doctor/serve.test.ts +95 -0
- package/src/doctor/serve.ts +86 -0
- package/src/doctor/structure.test.ts +423 -0
- package/src/doctor/structure.ts +285 -0
- package/src/doctor/types.ts +43 -0
- package/src/doctor/version.test.ts +241 -0
- package/src/doctor/version.ts +132 -0
- package/src/doctor/watchdog.test.ts +167 -0
- package/src/doctor/watchdog.ts +214 -0
- package/src/e2e/init-sling-lifecycle.test.ts +283 -0
- package/src/errors.test.ts +350 -0
- package/src/errors.ts +217 -0
- package/src/events/store.test.ts +660 -0
- package/src/events/store.ts +369 -0
- package/src/events/tailer.test.ts +719 -0
- package/src/events/tailer.ts +332 -0
- package/src/events/tool-filter.test.ts +330 -0
- package/src/events/tool-filter.ts +126 -0
- package/src/index.ts +533 -0
- package/src/insights/analyzer.test.ts +466 -0
- package/src/insights/analyzer.ts +203 -0
- package/src/insights/quality-gates.test.ts +141 -0
- package/src/insights/quality-gates.ts +156 -0
- package/src/json.test.ts +72 -0
- package/src/json.ts +53 -0
- package/src/loam/client.test.ts +752 -0
- package/src/loam/client.ts +664 -0
- package/src/logging/color.test.ts +252 -0
- package/src/logging/color.ts +105 -0
- package/src/logging/format.test.ts +110 -0
- package/src/logging/format.ts +255 -0
- package/src/logging/logger.test.ts +814 -0
- package/src/logging/logger.ts +266 -0
- package/src/logging/reporter.test.ts +259 -0
- package/src/logging/reporter.ts +110 -0
- package/src/logging/sanitizer.test.ts +190 -0
- package/src/logging/sanitizer.ts +57 -0
- package/src/logging/theme.ts +140 -0
- package/src/mail/broadcast.test.ts +204 -0
- package/src/mail/broadcast.ts +92 -0
- package/src/mail/client.test.ts +774 -0
- package/src/mail/client.ts +236 -0
- package/src/mail/store.test.ts +898 -0
- package/src/mail/store.ts +425 -0
- package/src/merge/lock.test.ts +149 -0
- package/src/merge/lock.ts +140 -0
- package/src/merge/predict.test.ts +387 -0
- package/src/merge/predict.ts +249 -0
- package/src/merge/queue.test.ts +426 -0
- package/src/merge/queue.ts +246 -0
- package/src/merge/resolver.test.ts +1993 -0
- package/src/merge/resolver.ts +926 -0
- package/src/metrics/pricing.test.ts +258 -0
- package/src/metrics/pricing.ts +135 -0
- package/src/metrics/store.test.ts +978 -0
- package/src/metrics/store.ts +501 -0
- package/src/metrics/summary.test.ts +398 -0
- package/src/metrics/summary.ts +178 -0
- package/src/metrics/transcript.test.ts +483 -0
- package/src/metrics/transcript.ts +114 -0
- package/src/runtimes/__fixtures__/claude-stream-fixture.ts +22 -0
- package/src/runtimes/aider.test.ts +124 -0
- package/src/runtimes/aider.ts +147 -0
- package/src/runtimes/amp.test.ts +164 -0
- package/src/runtimes/amp.ts +154 -0
- package/src/runtimes/claude.test.ts +1474 -0
- package/src/runtimes/claude.ts +579 -0
- package/src/runtimes/codex.test.ts +805 -0
- package/src/runtimes/codex.ts +273 -0
- package/src/runtimes/connections.test.ts +214 -0
- package/src/runtimes/connections.ts +103 -0
- package/src/runtimes/copilot.test.ts +707 -0
- package/src/runtimes/copilot.ts +316 -0
- package/src/runtimes/cursor.test.ts +497 -0
- package/src/runtimes/cursor.ts +205 -0
- package/src/runtimes/gemini.test.ts +537 -0
- package/src/runtimes/gemini.ts +243 -0
- package/src/runtimes/goose.test.ts +133 -0
- package/src/runtimes/goose.ts +157 -0
- package/src/runtimes/headless-connection.test.ts +264 -0
- package/src/runtimes/headless-connection.ts +158 -0
- package/src/runtimes/opencode.test.ts +325 -0
- package/src/runtimes/opencode.ts +188 -0
- package/src/runtimes/pi-guards.test.ts +486 -0
- package/src/runtimes/pi-guards.ts +367 -0
- package/src/runtimes/pi.test.ts +789 -0
- package/src/runtimes/pi.ts +305 -0
- package/src/runtimes/registry.test.ts +196 -0
- package/src/runtimes/registry.ts +99 -0
- package/src/runtimes/sapling.test.ts +1267 -0
- package/src/runtimes/sapling.ts +710 -0
- package/src/runtimes/types.ts +266 -0
- package/src/schema-consistency.test.ts +246 -0
- package/src/sessions/compat.test.ts +281 -0
- package/src/sessions/compat.ts +105 -0
- package/src/sessions/store.test.ts +1748 -0
- package/src/sessions/store.ts +858 -0
- package/src/test-helpers.test.ts +124 -0
- package/src/test-helpers.ts +145 -0
- package/src/test-setup.test.ts +31 -0
- package/src/test-setup.ts +28 -0
- package/src/tools/loam/api.ts +368 -0
- package/src/tools/loam/cli.ts +278 -0
- package/src/tools/loam/commands/add.ts +52 -0
- package/src/tools/loam/commands/archive.ts +214 -0
- package/src/tools/loam/commands/audit.ts +276 -0
- package/src/tools/loam/commands/compact.ts +1062 -0
- package/src/tools/loam/commands/completions.ts +79 -0
- package/src/tools/loam/commands/config.ts +381 -0
- package/src/tools/loam/commands/delete-domain.ts +121 -0
- package/src/tools/loam/commands/delete.ts +316 -0
- package/src/tools/loam/commands/diff.ts +200 -0
- package/src/tools/loam/commands/doctor.ts +1113 -0
- package/src/tools/loam/commands/edit.ts +226 -0
- package/src/tools/loam/commands/init.ts +31 -0
- package/src/tools/loam/commands/learn.ts +179 -0
- package/src/tools/loam/commands/move.ts +323 -0
- package/src/tools/loam/commands/onboard.ts +374 -0
- package/src/tools/loam/commands/outcome.ts +185 -0
- package/src/tools/loam/commands/prime.ts +688 -0
- package/src/tools/loam/commands/prune.ts +614 -0
- package/src/tools/loam/commands/query.ts +218 -0
- package/src/tools/loam/commands/rank.ts +180 -0
- package/src/tools/loam/commands/ready.ts +189 -0
- package/src/tools/loam/commands/record.ts +1210 -0
- package/src/tools/loam/commands/restore.ts +166 -0
- package/src/tools/loam/commands/search.ts +327 -0
- package/src/tools/loam/commands/setup.ts +887 -0
- package/src/tools/loam/commands/status.ts +103 -0
- package/src/tools/loam/commands/sync.ts +298 -0
- package/src/tools/loam/commands/update.ts +19 -0
- package/src/tools/loam/commands/upgrade.ts +93 -0
- package/src/tools/loam/commands/validate.ts +190 -0
- package/src/tools/loam/index.ts +62 -0
- package/src/tools/loam/log.ts +127 -0
- package/src/tools/loam/registry/builtins.ts +409 -0
- package/src/tools/loam/registry/custom.ts +431 -0
- package/src/tools/loam/registry/init.ts +55 -0
- package/src/tools/loam/registry/template.ts +40 -0
- package/src/tools/loam/registry/type-registry.ts +113 -0
- package/src/tools/loam/schemas/config-schema.ts +489 -0
- package/src/tools/loam/schemas/config.ts +245 -0
- package/src/tools/loam/schemas/index.ts +18 -0
- package/src/tools/loam/schemas/record-schema.ts +191 -0
- package/src/tools/loam/schemas/record.ts +115 -0
- package/src/tools/loam/utils/active-work.ts +205 -0
- package/src/tools/loam/utils/anchor-validity.ts +80 -0
- package/src/tools/loam/utils/archive.ts +146 -0
- package/src/tools/loam/utils/audit.ts +667 -0
- package/src/tools/loam/utils/bm25.ts +238 -0
- package/src/tools/loam/utils/budget.ts +142 -0
- package/src/tools/loam/utils/config.ts +344 -0
- package/src/tools/loam/utils/dir-anchors.ts +62 -0
- package/src/tools/loam/utils/domain-rules.ts +114 -0
- package/src/tools/loam/utils/expertise.ts +393 -0
- package/src/tools/loam/utils/format-helpers.ts +96 -0
- package/src/tools/loam/utils/format.ts +1234 -0
- package/src/tools/loam/utils/git-context.ts +50 -0
- package/src/tools/loam/utils/git.ts +183 -0
- package/src/tools/loam/utils/hooks.ts +299 -0
- package/src/tools/loam/utils/index.ts +52 -0
- package/src/tools/loam/utils/json-output.ts +13 -0
- package/src/tools/loam/utils/lock.ts +76 -0
- package/src/tools/loam/utils/markers.ts +48 -0
- package/src/tools/loam/utils/numeric-flags.ts +20 -0
- package/src/tools/loam/utils/palette.ts +44 -0
- package/src/tools/loam/utils/prime-ranking.ts +135 -0
- package/src/tools/loam/utils/recipe-discovery.ts +195 -0
- package/src/tools/loam/utils/runtime-flags.ts +28 -0
- package/src/tools/loam/utils/scoring.ts +94 -0
- package/src/tools/loam/utils/version.ts +116 -0
- package/src/tools/sprout/commands/block.ts +64 -0
- package/src/tools/sprout/commands/blocked.ts +86 -0
- package/src/tools/sprout/commands/close.ts +129 -0
- package/src/tools/sprout/commands/completions.ts +198 -0
- package/src/tools/sprout/commands/config.ts +238 -0
- package/src/tools/sprout/commands/create.ts +164 -0
- package/src/tools/sprout/commands/dep.ts +148 -0
- package/src/tools/sprout/commands/doctor.ts +979 -0
- package/src/tools/sprout/commands/init.ts +83 -0
- package/src/tools/sprout/commands/label.ts +178 -0
- package/src/tools/sprout/commands/list.ts +210 -0
- package/src/tools/sprout/commands/migrate.ts +133 -0
- package/src/tools/sprout/commands/onboard.ts +207 -0
- package/src/tools/sprout/commands/plan-show.ts +278 -0
- package/src/tools/sprout/commands/plan.ts +2526 -0
- package/src/tools/sprout/commands/prime.ts +399 -0
- package/src/tools/sprout/commands/ready.ts +245 -0
- package/src/tools/sprout/commands/search.ts +221 -0
- package/src/tools/sprout/commands/show.ts +277 -0
- package/src/tools/sprout/commands/stats.ts +146 -0
- package/src/tools/sprout/commands/sync.ts +134 -0
- package/src/tools/sprout/commands/tpl.ts +364 -0
- package/src/tools/sprout/commands/unblock.ts +115 -0
- package/src/tools/sprout/commands/update.ts +257 -0
- package/src/tools/sprout/commands/upgrade.ts +91 -0
- package/src/tools/sprout/config-schema.ts +152 -0
- package/src/tools/sprout/config.ts +355 -0
- package/src/tools/sprout/filter.ts +107 -0
- package/src/tools/sprout/format.ts +43 -0
- package/src/tools/sprout/id.ts +22 -0
- package/src/tools/sprout/index.ts +204 -0
- package/src/tools/sprout/log.ts +76 -0
- package/src/tools/sprout/markers.ts +22 -0
- package/src/tools/sprout/output.ts +121 -0
- package/src/tools/sprout/plan-backref.ts +93 -0
- package/src/tools/sprout/plan-context.ts +81 -0
- package/src/tools/sprout/plan-domain.ts +139 -0
- package/src/tools/sprout/plan-lifecycle.ts +65 -0
- package/src/tools/sprout/plan-loam.ts +207 -0
- package/src/tools/sprout/plan-schema.ts +209 -0
- package/src/tools/sprout/sort.ts +31 -0
- package/src/tools/sprout/store.ts +172 -0
- package/src/tools/sprout/types.ts +118 -0
- package/src/tools/sprout/validation.ts +119 -0
- package/src/tools/sprout/version.ts +1 -0
- package/src/tools/sprout/yaml.ts +387 -0
- package/src/tools/trellis/commands/archive.ts +87 -0
- package/src/tools/trellis/commands/completions.ts +610 -0
- package/src/tools/trellis/commands/config.ts +382 -0
- package/src/tools/trellis/commands/create.ts +252 -0
- package/src/tools/trellis/commands/diff.ts +150 -0
- package/src/tools/trellis/commands/doctor.ts +771 -0
- package/src/tools/trellis/commands/emit.ts +365 -0
- package/src/tools/trellis/commands/history.ts +83 -0
- package/src/tools/trellis/commands/import.ts +198 -0
- package/src/tools/trellis/commands/init.ts +81 -0
- package/src/tools/trellis/commands/list.ts +103 -0
- package/src/tools/trellis/commands/onboard.ts +156 -0
- package/src/tools/trellis/commands/pin.ts +172 -0
- package/src/tools/trellis/commands/prime.ts +193 -0
- package/src/tools/trellis/commands/render.ts +122 -0
- package/src/tools/trellis/commands/schema.ts +353 -0
- package/src/tools/trellis/commands/show.ts +115 -0
- package/src/tools/trellis/commands/stats.ts +65 -0
- package/src/tools/trellis/commands/sync.ts +112 -0
- package/src/tools/trellis/commands/tree.ts +123 -0
- package/src/tools/trellis/commands/update.ts +330 -0
- package/src/tools/trellis/commands/upgrade.ts +95 -0
- package/src/tools/trellis/commands/validate.ts +166 -0
- package/src/tools/trellis/config-schema.ts +81 -0
- package/src/tools/trellis/config.ts +108 -0
- package/src/tools/trellis/frontmatter.ts +348 -0
- package/src/tools/trellis/id.ts +24 -0
- package/src/tools/trellis/index.ts +209 -0
- package/src/tools/trellis/markers.ts +28 -0
- package/src/tools/trellis/output.ts +84 -0
- package/src/tools/trellis/render.ts +212 -0
- package/src/tools/trellis/store.ts +144 -0
- package/src/tools/trellis/types.ts +82 -0
- package/src/tools/trellis/validate.ts +199 -0
- package/src/tools/trellis/yaml.ts +309 -0
- package/src/tracker/beads.test.ts +454 -0
- package/src/tracker/beads.ts +56 -0
- package/src/tracker/factory.test.ts +90 -0
- package/src/tracker/factory.ts +65 -0
- package/src/tracker/sprout.test.ts +461 -0
- package/src/tracker/sprout.ts +182 -0
- package/src/tracker/types.ts +52 -0
- package/src/trellis/client.test.ts +107 -0
- package/src/trellis/client.ts +179 -0
- package/src/types.ts +970 -0
- package/src/utils/bin.test.ts +10 -0
- package/src/utils/bin.ts +37 -0
- package/src/utils/browser.test.ts +49 -0
- package/src/utils/browser.ts +48 -0
- package/src/utils/fs.test.ts +119 -0
- package/src/utils/fs.ts +62 -0
- package/src/utils/pid.test.ts +152 -0
- package/src/utils/pid.ts +130 -0
- package/src/utils/process-scan.test.ts +53 -0
- package/src/utils/process-scan.ts +76 -0
- package/src/utils/time.test.ts +43 -0
- package/src/utils/time.ts +37 -0
- package/src/utils/version.test.ts +33 -0
- package/src/utils/version.ts +70 -0
- package/src/version.ts +5 -0
- package/src/watchdog/daemon.test.ts +3721 -0
- package/src/watchdog/daemon.ts +1257 -0
- package/src/watchdog/health.test.ts +830 -0
- package/src/watchdog/health.ts +434 -0
- package/src/watchdog/triage.test.ts +205 -0
- package/src/watchdog/triage.ts +205 -0
- package/src/worktree/manager.test.ts +720 -0
- package/src/worktree/manager.ts +405 -0
- package/src/worktree/process.test.ts +172 -0
- package/src/worktree/process.ts +131 -0
- package/src/worktree/tmux.test.ts +1616 -0
- package/src/worktree/tmux.ts +721 -0
- package/templates/CLAUDE.md.tmpl +100 -0
- package/templates/copilot-hooks.json.tmpl +13 -0
- package/templates/hooks.json.tmpl +109 -0
- package/templates/overlay.md.tmpl +88 -0
- package/ui/dist/apple-touch-icon-bdy6teep.png +0 -0
- package/ui/dist/chunk-8s31f05k.css +1 -0
- package/ui/dist/chunk-vm5rz679.js +300 -0
- package/ui/dist/favicon-nzb39vza.svg +4 -0
- package/ui/dist/index.html +17 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import type { Command } from "commander";
|
|
3
|
+
import type { ExpertiseRecord } from "../schemas/record.ts";
|
|
4
|
+
import {
|
|
5
|
+
archiveRecords,
|
|
6
|
+
getArchivePath,
|
|
7
|
+
readArchiveFile,
|
|
8
|
+
removeFromArchive,
|
|
9
|
+
restoreToExpertise,
|
|
10
|
+
stripArchiveFields,
|
|
11
|
+
} from "../utils/archive.ts";
|
|
12
|
+
import { getExpertisePath, readConfig } from "../utils/config.ts";
|
|
13
|
+
import { readExpertiseFile, resolveRecordId } from "../utils/expertise.ts";
|
|
14
|
+
import { getRecordSummary } from "../utils/format.ts";
|
|
15
|
+
import { outputJson, outputJsonError } from "../utils/json-output.ts";
|
|
16
|
+
import { accent, brand, isQuiet } from "../utils/palette.ts";
|
|
17
|
+
|
|
18
|
+
export function registerRestoreCommand(program: Command): void {
|
|
19
|
+
program
|
|
20
|
+
.command("restore")
|
|
21
|
+
.argument("<id>", "archived record ID (e.g. mx-abc123, abc123, or abc)")
|
|
22
|
+
.description("Restore a soft-archived record from .loam/archive/ back to live expertise")
|
|
23
|
+
.action(async (id: string) => {
|
|
24
|
+
const jsonMode = program.opts().json === true;
|
|
25
|
+
try {
|
|
26
|
+
const config = await readConfig();
|
|
27
|
+
|
|
28
|
+
// Search every archive file for the record id. Records carry no
|
|
29
|
+
// domain field, so we have to scan domain by domain. The id space
|
|
30
|
+
// is sha-derived and effectively unique, so collisions across
|
|
31
|
+
// domain archives are vanishingly rare; surface them as an error
|
|
32
|
+
// when they do happen.
|
|
33
|
+
const matches: Array<{ domain: string; record: ExpertiseRecord }> = [];
|
|
34
|
+
for (const domain of Object.keys(config.domains)) {
|
|
35
|
+
const archivePath = getArchivePath(domain);
|
|
36
|
+
const records = await readArchiveFile(archivePath);
|
|
37
|
+
const resolved = resolveRecordId(records, id);
|
|
38
|
+
if (resolved.ok) {
|
|
39
|
+
matches.push({ domain, record: resolved.record });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (matches.length === 0) {
|
|
44
|
+
const msg = `Archived record "${id}" not found in any domain. Run \`lm search --archived <query>\` to browse archives.`;
|
|
45
|
+
if (jsonMode) {
|
|
46
|
+
outputJsonError("restore", msg);
|
|
47
|
+
} else {
|
|
48
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
49
|
+
}
|
|
50
|
+
process.exitCode = 1;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (matches.length > 1) {
|
|
55
|
+
const where = matches.map((m) => `${m.domain} (${m.record.id})`).join(", ");
|
|
56
|
+
const msg = `Identifier "${id}" matches archived records in multiple domains: ${where}. Use a longer prefix.`;
|
|
57
|
+
if (jsonMode) {
|
|
58
|
+
outputJsonError("restore", msg);
|
|
59
|
+
} else {
|
|
60
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
61
|
+
}
|
|
62
|
+
process.exitCode = 1;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const target = matches[0];
|
|
67
|
+
if (!target) return;
|
|
68
|
+
const { domain, record } = target;
|
|
69
|
+
const recordId = record.id;
|
|
70
|
+
if (!recordId) {
|
|
71
|
+
const msg = `Archived record has no id; cannot restore safely.`;
|
|
72
|
+
if (jsonMode) {
|
|
73
|
+
outputJsonError("restore", msg);
|
|
74
|
+
} else {
|
|
75
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
76
|
+
}
|
|
77
|
+
process.exitCode = 1;
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Pre-check: refuse to restore over an existing live id BEFORE touching
|
|
82
|
+
// the archive. Race-safe re-check happens inside restoreToExpertise
|
|
83
|
+
// under the live file's lock; if that catches a duplicate we'll roll
|
|
84
|
+
// the archive back below.
|
|
85
|
+
const expertisePath = getExpertisePath(domain);
|
|
86
|
+
const liveExisting = await readExpertiseFile(expertisePath);
|
|
87
|
+
const livePreConflict = liveExisting.find((r) => r.id === recordId);
|
|
88
|
+
if (livePreConflict) {
|
|
89
|
+
const msg = `Live record "${recordId}" already exists in domain "${domain}" (classification: ${livePreConflict.classification}). Delete or rename the live record before restoring, or run \`lm search --archived ${recordId}\` to inspect the archived copy.`;
|
|
90
|
+
if (jsonMode) {
|
|
91
|
+
outputJsonError("restore", msg);
|
|
92
|
+
} else {
|
|
93
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
94
|
+
}
|
|
95
|
+
process.exitCode = 1;
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const removed = await removeFromArchive(domain, recordId);
|
|
100
|
+
if (!removed) {
|
|
101
|
+
const msg = `Archived record "${recordId}" disappeared between read and write (concurrent restore?).`;
|
|
102
|
+
if (jsonMode) {
|
|
103
|
+
outputJsonError("restore", msg);
|
|
104
|
+
} else {
|
|
105
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
106
|
+
}
|
|
107
|
+
process.exitCode = 1;
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Capture the original archive_reason BEFORE stripping so we can
|
|
112
|
+
// surface it in the success line and preserve it on a rollback
|
|
113
|
+
// re-archive. Archives written before loam-b41a have no reason
|
|
114
|
+
// on disk — fall back to "manual" so the field is always set.
|
|
115
|
+
const originalReason = removed.archive_reason ?? "manual";
|
|
116
|
+
const live = stripArchiveFields(removed);
|
|
117
|
+
const restoreRes = await restoreToExpertise(expertisePath, live);
|
|
118
|
+
if (!restoreRes.ok) {
|
|
119
|
+
// Race lost between pre-check and lock. Roll the archive back so
|
|
120
|
+
// the record isn't stranded. Preserve the original archive_reason
|
|
121
|
+
// so the round-trip is invisible to anyone reading the archive.
|
|
122
|
+
await archiveRecords(domain, [stripArchiveFields(removed)], new Date(), originalReason);
|
|
123
|
+
const msg = `Live record "${recordId}" appeared in domain "${domain}" while restore was in flight (classification: ${restoreRes.conflict.classification}). Re-archived; nothing changed.`;
|
|
124
|
+
if (jsonMode) {
|
|
125
|
+
outputJsonError("restore", msg);
|
|
126
|
+
} else {
|
|
127
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
128
|
+
}
|
|
129
|
+
process.exitCode = 1;
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (jsonMode) {
|
|
134
|
+
outputJson({
|
|
135
|
+
success: true,
|
|
136
|
+
command: "restore",
|
|
137
|
+
domain,
|
|
138
|
+
id: live.id ?? null,
|
|
139
|
+
type: live.type,
|
|
140
|
+
summary: getRecordSummary(live),
|
|
141
|
+
archive_reason: originalReason,
|
|
142
|
+
});
|
|
143
|
+
} else if (!isQuiet()) {
|
|
144
|
+
const rid = live.id ? ` ${accent(live.id)}` : "";
|
|
145
|
+
console.log(
|
|
146
|
+
`${brand("✓")} ${brand(`Restored ${live.type}`)}${rid} ${brand(`to ${domain}`)} (archived: ${originalReason}): ${getRecordSummary(live)}`,
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
} catch (err) {
|
|
150
|
+
if ((err as NodeJS.ErrnoException).code === "ENOENT") {
|
|
151
|
+
if (jsonMode) {
|
|
152
|
+
outputJsonError("restore", "No .loam/ directory found. Run `loam init` first.");
|
|
153
|
+
} else {
|
|
154
|
+
console.error(chalk.red("Error: No .loam/ directory found. Run `loam init` first."));
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
if (jsonMode) {
|
|
158
|
+
outputJsonError("restore", (err as Error).message);
|
|
159
|
+
} else {
|
|
160
|
+
console.error(chalk.red(`Error: ${(err as Error).message}`));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
process.exitCode = 1;
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { type Command, Option } from "commander";
|
|
3
|
+
import { getRegistry } from "../registry/type-registry.ts";
|
|
4
|
+
import { DEFAULT_SEARCH_BOOST_FACTOR } from "../schemas/config.ts";
|
|
5
|
+
import type { ExpertiseRecord } from "../schemas/record.ts";
|
|
6
|
+
import { getArchivePath, readArchiveFile } from "../utils/archive.ts";
|
|
7
|
+
import { getExpertisePath, readConfig } from "../utils/config.ts";
|
|
8
|
+
import {
|
|
9
|
+
filterByClassification,
|
|
10
|
+
filterByFile,
|
|
11
|
+
filterByType,
|
|
12
|
+
getFileModTime,
|
|
13
|
+
readExpertiseFile,
|
|
14
|
+
searchRecords,
|
|
15
|
+
} from "../utils/expertise.ts";
|
|
16
|
+
import {
|
|
17
|
+
formatDomainExpertise,
|
|
18
|
+
formatDomainExpertiseCompact,
|
|
19
|
+
formatDomainExpertisePlain,
|
|
20
|
+
formatDomainExpertiseXml,
|
|
21
|
+
getRecordSummary,
|
|
22
|
+
type PrimeFormat,
|
|
23
|
+
} from "../utils/format.ts";
|
|
24
|
+
import { outputJson, outputJsonError } from "../utils/json-output.ts";
|
|
25
|
+
import { type ScoredRecord, sortByConfirmationScore } from "../utils/scoring.ts";
|
|
26
|
+
|
|
27
|
+
function formatArchivedSection(domain: string, records: ExpertiseRecord[]): string {
|
|
28
|
+
const lines = [
|
|
29
|
+
`## ${domain} (archived, ${records.length} record${records.length === 1 ? "" : "s"})`,
|
|
30
|
+
];
|
|
31
|
+
for (const r of records) {
|
|
32
|
+
const date = (r.archived_at ?? "").slice(0, 10) || "unknown";
|
|
33
|
+
const id = r.id ? `${r.id} ` : "";
|
|
34
|
+
// Archives written before loam-b41a have no reason on disk; omit the
|
|
35
|
+
// suffix gracefully so back-compat output stays readable.
|
|
36
|
+
const reason = r.archive_reason ? ` ${r.archive_reason}` : "";
|
|
37
|
+
lines.push(`- [ARCHIVED ${date}${reason}] ${id}[${r.type}] ${getRecordSummary(r)}`);
|
|
38
|
+
}
|
|
39
|
+
return lines.join("\n");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function applyFilters(
|
|
43
|
+
records: ExpertiseRecord[],
|
|
44
|
+
options: {
|
|
45
|
+
type?: string;
|
|
46
|
+
tag?: string;
|
|
47
|
+
classification?: string;
|
|
48
|
+
file?: string;
|
|
49
|
+
outcomeStatus?: string;
|
|
50
|
+
},
|
|
51
|
+
): ExpertiseRecord[] {
|
|
52
|
+
let out = records;
|
|
53
|
+
if (options.type) out = filterByType(out, options.type);
|
|
54
|
+
if (options.tag) {
|
|
55
|
+
const tagLower = options.tag.toLowerCase();
|
|
56
|
+
out = out.filter((r) => r.tags?.some((t) => t.toLowerCase() === tagLower));
|
|
57
|
+
}
|
|
58
|
+
if (options.classification) out = filterByClassification(out, options.classification);
|
|
59
|
+
if (options.file) out = filterByFile(out, options.file);
|
|
60
|
+
if (options.outcomeStatus) {
|
|
61
|
+
out = out.filter((r) => r.outcomes?.some((o) => o.status === options.outcomeStatus));
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function registerSearchCommand(program: Command): void {
|
|
67
|
+
program
|
|
68
|
+
.command("search")
|
|
69
|
+
.argument("[query]", "search string (case-insensitive substring match)")
|
|
70
|
+
.description("Search expertise records across domains")
|
|
71
|
+
.option("--domain <domain>", "limit search to a specific domain")
|
|
72
|
+
.addOption(new Option("--type <type>", "filter by record type").choices(getRegistry().names()))
|
|
73
|
+
.option("--tag <tag>", "filter by tag")
|
|
74
|
+
.addOption(
|
|
75
|
+
new Option("--classification <classification>", "filter by classification").choices([
|
|
76
|
+
"foundational",
|
|
77
|
+
"tactical",
|
|
78
|
+
"observational",
|
|
79
|
+
]),
|
|
80
|
+
)
|
|
81
|
+
.option("--file <file>", "filter by associated file path (substring match)")
|
|
82
|
+
.addOption(
|
|
83
|
+
new Option("--outcome-status <status>", "filter by outcome status").choices([
|
|
84
|
+
"success",
|
|
85
|
+
"failure",
|
|
86
|
+
"partial",
|
|
87
|
+
]),
|
|
88
|
+
)
|
|
89
|
+
.option("--sort-by-score", "sort results by confirmation-frequency score (highest first)")
|
|
90
|
+
.option("--no-boost", "disable confirmation-frequency boost on BM25 ranking (pure BM25)")
|
|
91
|
+
.option("--archived", "include soft-archived records from .loam/archive/ (excluded by default)")
|
|
92
|
+
.addOption(
|
|
93
|
+
new Option("--format <format>", "output format for records").choices([
|
|
94
|
+
"markdown",
|
|
95
|
+
"compact",
|
|
96
|
+
"xml",
|
|
97
|
+
"plain",
|
|
98
|
+
"ids",
|
|
99
|
+
]),
|
|
100
|
+
)
|
|
101
|
+
.action(
|
|
102
|
+
async (
|
|
103
|
+
query: string | undefined,
|
|
104
|
+
options: {
|
|
105
|
+
domain?: string;
|
|
106
|
+
type?: string;
|
|
107
|
+
tag?: string;
|
|
108
|
+
classification?: string;
|
|
109
|
+
file?: string;
|
|
110
|
+
outcomeStatus?: string;
|
|
111
|
+
sortByScore?: boolean;
|
|
112
|
+
boost?: boolean;
|
|
113
|
+
format?: string;
|
|
114
|
+
archived?: boolean;
|
|
115
|
+
},
|
|
116
|
+
) => {
|
|
117
|
+
const jsonMode = program.opts().json === true;
|
|
118
|
+
try {
|
|
119
|
+
if (
|
|
120
|
+
!query &&
|
|
121
|
+
!options.type &&
|
|
122
|
+
!options.domain &&
|
|
123
|
+
!options.tag &&
|
|
124
|
+
!options.classification &&
|
|
125
|
+
!options.file &&
|
|
126
|
+
!options.outcomeStatus
|
|
127
|
+
) {
|
|
128
|
+
if (jsonMode) {
|
|
129
|
+
outputJsonError(
|
|
130
|
+
"search",
|
|
131
|
+
"Provide a search query or use --type, --domain, --tag, --classification, --file, or --outcome-status to filter.",
|
|
132
|
+
);
|
|
133
|
+
} else {
|
|
134
|
+
console.error(
|
|
135
|
+
"Error: Provide a search query or use --type, --domain, --tag, --classification, --file, or --outcome-status to filter.",
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
process.exitCode = 1;
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const config = await readConfig();
|
|
143
|
+
const boostFactor =
|
|
144
|
+
options.boost === false
|
|
145
|
+
? 0
|
|
146
|
+
: (config.search?.boost_factor ?? DEFAULT_SEARCH_BOOST_FACTOR);
|
|
147
|
+
|
|
148
|
+
let domainsToSearch: string[];
|
|
149
|
+
|
|
150
|
+
if (options.domain) {
|
|
151
|
+
if (!(options.domain in config.domains)) {
|
|
152
|
+
if (jsonMode) {
|
|
153
|
+
outputJsonError(
|
|
154
|
+
"search",
|
|
155
|
+
`Domain "${options.domain}" not found in config. Available domains: ${Object.keys(config.domains).join(", ")}`,
|
|
156
|
+
);
|
|
157
|
+
} else {
|
|
158
|
+
console.error(
|
|
159
|
+
`Error: Domain "${options.domain}" not found in config. Available domains: ${Object.keys(config.domains).join(", ")}`,
|
|
160
|
+
);
|
|
161
|
+
console.error(
|
|
162
|
+
`Hint: Run \`loam add ${options.domain}\` to create this domain, or check .loam/loam.config.yaml`,
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
process.exitCode = 1;
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
domainsToSearch = [options.domain];
|
|
169
|
+
} else {
|
|
170
|
+
domainsToSearch = Object.keys(config.domains);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
let totalMatches = 0;
|
|
174
|
+
|
|
175
|
+
if (jsonMode) {
|
|
176
|
+
const result: Array<{
|
|
177
|
+
domain: string;
|
|
178
|
+
matches: unknown[];
|
|
179
|
+
archived?: unknown[];
|
|
180
|
+
}> = [];
|
|
181
|
+
for (const domain of domainsToSearch) {
|
|
182
|
+
const filePath = getExpertisePath(domain);
|
|
183
|
+
const records = applyFilters(await readExpertiseFile(filePath), options);
|
|
184
|
+
let matches = query ? searchRecords(records, query, { boostFactor }) : records;
|
|
185
|
+
if (options.sortByScore) {
|
|
186
|
+
matches = sortByConfirmationScore(matches as ScoredRecord[]);
|
|
187
|
+
}
|
|
188
|
+
let archivedMatches: ExpertiseRecord[] = [];
|
|
189
|
+
if (options.archived) {
|
|
190
|
+
const archiveRecords = applyFilters(
|
|
191
|
+
await readArchiveFile(getArchivePath(domain)),
|
|
192
|
+
options,
|
|
193
|
+
);
|
|
194
|
+
archivedMatches = query
|
|
195
|
+
? searchRecords(archiveRecords, query, { boostFactor })
|
|
196
|
+
: archiveRecords;
|
|
197
|
+
if (options.sortByScore) {
|
|
198
|
+
archivedMatches = sortByConfirmationScore(archivedMatches as ScoredRecord[]);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (matches.length > 0 || archivedMatches.length > 0) {
|
|
202
|
+
totalMatches += matches.length + archivedMatches.length;
|
|
203
|
+
const entry: { domain: string; matches: unknown[]; archived?: unknown[] } = {
|
|
204
|
+
domain,
|
|
205
|
+
matches,
|
|
206
|
+
};
|
|
207
|
+
if (options.archived) entry.archived = archivedMatches;
|
|
208
|
+
result.push(entry);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
outputJson({
|
|
212
|
+
success: true,
|
|
213
|
+
command: "search",
|
|
214
|
+
query: query ?? null,
|
|
215
|
+
total: totalMatches,
|
|
216
|
+
domains: result,
|
|
217
|
+
});
|
|
218
|
+
} else {
|
|
219
|
+
const globalFormat = program.opts().format as PrimeFormat | undefined;
|
|
220
|
+
const fmt = options.format ?? (globalFormat as string | undefined) ?? "markdown";
|
|
221
|
+
const label = query ? `matching "${query}"` : "matching filters";
|
|
222
|
+
|
|
223
|
+
if (fmt === "ids") {
|
|
224
|
+
const ids: string[] = [];
|
|
225
|
+
for (const domain of domainsToSearch) {
|
|
226
|
+
const filePath = getExpertisePath(domain);
|
|
227
|
+
const records = applyFilters(await readExpertiseFile(filePath), options);
|
|
228
|
+
let matches = query ? searchRecords(records, query, { boostFactor }) : records;
|
|
229
|
+
if (options.sortByScore) {
|
|
230
|
+
matches = sortByConfirmationScore(matches as ScoredRecord[]);
|
|
231
|
+
}
|
|
232
|
+
for (const r of matches) {
|
|
233
|
+
if (r.id) ids.push(r.id);
|
|
234
|
+
}
|
|
235
|
+
if (options.archived) {
|
|
236
|
+
const archiveRecords = applyFilters(
|
|
237
|
+
await readArchiveFile(getArchivePath(domain)),
|
|
238
|
+
options,
|
|
239
|
+
);
|
|
240
|
+
let archivedMatches = query
|
|
241
|
+
? searchRecords(archiveRecords, query, { boostFactor })
|
|
242
|
+
: archiveRecords;
|
|
243
|
+
if (options.sortByScore) {
|
|
244
|
+
archivedMatches = sortByConfirmationScore(archivedMatches as ScoredRecord[]);
|
|
245
|
+
}
|
|
246
|
+
for (const r of archivedMatches) {
|
|
247
|
+
if (r.id) ids.push(r.id);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
if (ids.length === 0) {
|
|
252
|
+
console.log(`No records ${label} found.`);
|
|
253
|
+
} else {
|
|
254
|
+
console.log(ids.join("\n"));
|
|
255
|
+
}
|
|
256
|
+
} else {
|
|
257
|
+
const sections: string[] = [];
|
|
258
|
+
for (const domain of domainsToSearch) {
|
|
259
|
+
const filePath = getExpertisePath(domain);
|
|
260
|
+
const records = applyFilters(await readExpertiseFile(filePath), options);
|
|
261
|
+
const lastUpdated = await getFileModTime(filePath);
|
|
262
|
+
let matches = query ? searchRecords(records, query, { boostFactor }) : records;
|
|
263
|
+
if (options.sortByScore) {
|
|
264
|
+
matches = sortByConfirmationScore(matches as ScoredRecord[]);
|
|
265
|
+
}
|
|
266
|
+
if (matches.length > 0) {
|
|
267
|
+
totalMatches += matches.length;
|
|
268
|
+
switch (fmt) {
|
|
269
|
+
case "compact":
|
|
270
|
+
sections.push(formatDomainExpertiseCompact(domain, matches, lastUpdated));
|
|
271
|
+
break;
|
|
272
|
+
case "xml":
|
|
273
|
+
sections.push(formatDomainExpertiseXml(domain, matches, lastUpdated));
|
|
274
|
+
break;
|
|
275
|
+
case "plain":
|
|
276
|
+
sections.push(formatDomainExpertisePlain(domain, matches, lastUpdated));
|
|
277
|
+
break;
|
|
278
|
+
default:
|
|
279
|
+
sections.push(formatDomainExpertise(domain, matches, lastUpdated));
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (options.archived) {
|
|
284
|
+
const archiveRecords = applyFilters(
|
|
285
|
+
await readArchiveFile(getArchivePath(domain)),
|
|
286
|
+
options,
|
|
287
|
+
);
|
|
288
|
+
let archivedMatches = query
|
|
289
|
+
? searchRecords(archiveRecords, query, { boostFactor })
|
|
290
|
+
: archiveRecords;
|
|
291
|
+
if (options.sortByScore) {
|
|
292
|
+
archivedMatches = sortByConfirmationScore(archivedMatches as ScoredRecord[]);
|
|
293
|
+
}
|
|
294
|
+
if (archivedMatches.length > 0) {
|
|
295
|
+
totalMatches += archivedMatches.length;
|
|
296
|
+
sections.push(formatArchivedSection(domain, archivedMatches));
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (sections.length === 0) {
|
|
302
|
+
console.log(`No records ${label} found.`);
|
|
303
|
+
} else {
|
|
304
|
+
console.log(sections.join("\n\n"));
|
|
305
|
+
console.log(`\n${totalMatches} match${totalMatches === 1 ? "" : "es"} found.`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
} catch (err) {
|
|
310
|
+
if ((err as NodeJS.ErrnoException).code === "ENOENT") {
|
|
311
|
+
if (jsonMode) {
|
|
312
|
+
outputJsonError("search", "No .loam/ directory found. Run `loam init` first.");
|
|
313
|
+
} else {
|
|
314
|
+
console.error(chalk.red("Error: No .loam/ directory found. Run `loam init` first."));
|
|
315
|
+
}
|
|
316
|
+
} else {
|
|
317
|
+
if (jsonMode) {
|
|
318
|
+
outputJsonError("search", (err as Error).message);
|
|
319
|
+
} else {
|
|
320
|
+
console.error(chalk.red(`Error: ${(err as Error).message}`));
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
process.exitCode = 1;
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
);
|
|
327
|
+
}
|