@lore-co/cli 0.2.13 → 0.2.15
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/README.md +84 -11
- package/dist/capture-scope.d.ts +12 -0
- package/dist/capture-scope.d.ts.map +1 -0
- package/dist/capture-scope.js +45 -0
- package/dist/capture-scope.js.map +1 -0
- package/dist/cli.d.ts +7 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +118 -36
- package/dist/cli.js.map +1 -1
- package/dist/command-help.d.ts +2 -1
- package/dist/command-help.d.ts.map +1 -1
- package/dist/command-help.js +4 -1
- package/dist/command-help.js.map +1 -1
- package/dist/connect-project.d.ts +15 -0
- package/dist/connect-project.d.ts.map +1 -0
- package/dist/connect-project.js +87 -0
- package/dist/connect-project.js.map +1 -0
- package/dist/connections.d.ts +3 -1
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +6 -1
- package/dist/connections.js.map +1 -1
- package/dist/devin-cli.d.ts.map +1 -1
- package/dist/devin-cli.js +14 -6
- package/dist/devin-cli.js.map +1 -1
- package/dist/devin.d.ts.map +1 -1
- package/dist/devin.js +5 -2
- package/dist/devin.js.map +1 -1
- package/dist/generated-assets.d.ts +7 -6
- package/dist/generated-assets.d.ts.map +1 -1
- package/dist/generated-assets.js +6 -5
- package/dist/generated-assets.js.map +1 -1
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +5 -5
- package/dist/host.js.map +1 -1
- package/dist/recovery-cloud.js +1 -1
- package/dist/recovery-cloud.js.map +1 -1
- package/dist/recovery-remote.d.ts +1 -1
- package/dist/recovery-remote.d.ts.map +1 -1
- package/dist/recovery-remote.js +4 -2
- package/dist/recovery-remote.js.map +1 -1
- package/dist/recovery-state.d.ts.map +1 -1
- package/dist/recovery-state.js +5 -0
- package/dist/recovery-state.js.map +1 -1
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +3 -3
- package/dist/recovery.js.map +1 -1
- package/dist/reliability-store.d.ts.map +1 -1
- package/dist/reliability-store.js +4 -1
- package/dist/reliability-store.js.map +1 -1
- package/dist/remember.d.ts.map +1 -1
- package/dist/remember.js +8 -1
- package/dist/remember.js.map +1 -1
- package/dist/retrieval-task.d.ts +20 -0
- package/dist/retrieval-task.d.ts.map +1 -0
- package/dist/retrieval-task.js +78 -0
- package/dist/retrieval-task.js.map +1 -0
- package/dist/runtime-redaction.d.ts +2 -0
- package/dist/runtime-redaction.d.ts.map +1 -0
- package/dist/runtime-redaction.js +69 -0
- package/dist/runtime-redaction.js.map +1 -0
- package/dist/runtime.d.ts +2 -2
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +45 -70
- package/dist/runtime.js.map +1 -1
- package/dist/self-host.d.ts +2 -1
- package/dist/self-host.d.ts.map +1 -1
- package/dist/self-host.js +6 -4
- package/dist/self-host.js.map +1 -1
- package/dist/signed-snapshot.d.ts.map +1 -1
- package/dist/signed-snapshot.js +2 -0
- package/dist/signed-snapshot.js.map +1 -1
- package/dist/skill-command.d.ts +20 -0
- package/dist/skill-command.d.ts.map +1 -0
- package/dist/skill-command.js +215 -0
- package/dist/skill-command.js.map +1 -0
- package/dist/skill-guidance.d.ts +2 -0
- package/dist/skill-guidance.d.ts.map +1 -0
- package/dist/skill-guidance.js +7 -0
- package/dist/skill-guidance.js.map +1 -0
- package/dist/skills.d.ts +16 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +126 -0
- package/dist/skills.js.map +1 -0
- package/dist/update.js +3 -3
- package/package.json +7 -3
package/dist/cli.js
CHANGED
|
@@ -4,6 +4,8 @@ import { reportCommand, runTelemetryCommand, telemetryEnabled, trackedCommand, T
|
|
|
4
4
|
import { secureWindowsDirectory, windowsPermissionsArePrivate } from "./windows-permissions.js";
|
|
5
5
|
import { COMMAND_GUIDES, ROOT_HELP, helpTopic } from "./command-help.js";
|
|
6
6
|
import { runShareCommand } from "./share.js";
|
|
7
|
+
import { resolveConnectProject, validateConnectProjectOptions } from "./connect-project.js";
|
|
8
|
+
import { captureDirectories } from "./capture-scope.js";
|
|
7
9
|
import { prepareConnection, persistConnection, listConnections } from "./connections.js";
|
|
8
10
|
import { connectionReferences, resolveLocalConnection } from "./directory-policy.js";
|
|
9
11
|
import { withDirectoryLock } from "./reliability-store.js";
|
|
@@ -23,7 +25,9 @@ import { runHook, } from "./runtime.js";
|
|
|
23
25
|
import { readInvocationHealthWriteInput, runInvocationHealthWrite, } from "./invocation-health-writer.js";
|
|
24
26
|
import { runAskCommand } from "./ask.js";
|
|
25
27
|
import { runRememberCommand } from "./remember.js";
|
|
28
|
+
import { installLoreSkill, removeLoreSkill } from "./skills.js";
|
|
26
29
|
import { runApproachCommand } from "./approach.js";
|
|
30
|
+
import { runSkillCommand } from "./skill-command.js";
|
|
27
31
|
import { runGuardCommand } from "./guard.js";
|
|
28
32
|
import { runContinueCommand, runResumeCommand } from "./handoff.js";
|
|
29
33
|
import { disableRecovery, prepareAutomaticRecovery, prepareRecoveryInstallation, runRecoveryCommand, runRecoveryHook, runWrappedAgent } from "./recovery.js";
|
|
@@ -97,6 +101,11 @@ Usage:
|
|
|
97
101
|
|
|
98
102
|
Options:
|
|
99
103
|
--name <name> Name this account/workspace connection (e.g. work)
|
|
104
|
+
--current-project Confirm and record the current Git project
|
|
105
|
+
--choose-folder Open a folder picker on this machine
|
|
106
|
+
--repository <repo> Verify the selected folder matches this GitHub repository
|
|
107
|
+
--folder <path> Record only in this folder and subfolders (repeatable)
|
|
108
|
+
--all-projects Record in all projects allowed by your workspace
|
|
100
109
|
--url <url> Lore API base URL (default: https://api.uselore.co)
|
|
101
110
|
--dashboard-url <url> Lore dashboard URL (default: https://uselore.co for hosted Lore)
|
|
102
111
|
--login Approve access securely in the Lore dashboard
|
|
@@ -109,8 +118,12 @@ Options:
|
|
|
109
118
|
--json Print machine-readable output
|
|
110
119
|
--help Show this command's help
|
|
111
120
|
|
|
121
|
+
New connections stay paused until you choose a project, a folder, or --all-projects.
|
|
122
|
+
Reconnecting without a capture option keeps your saved folder rules.
|
|
123
|
+
Folder choices control capture; learning scope controls where knowledge applies.
|
|
124
|
+
|
|
112
125
|
Examples:
|
|
113
|
-
lore connect --login --agent claude
|
|
126
|
+
lore connect --login --agent claude --folder .
|
|
114
127
|
lore connect --login --agent cowork
|
|
115
128
|
lore connect --token "$LORE_WORKSPACE_TOKEN" --agent claude
|
|
116
129
|
lore connect --url http://localhost:3004 --token dev-token --agent codex
|
|
@@ -1421,7 +1434,11 @@ async function installRuntime(paths) {
|
|
|
1421
1434
|
rm(resolve(dirname(paths.runtime), "image-bytes.js"), { force: true }),
|
|
1422
1435
|
rm(resolve(dirname(paths.runtime), "image-capture.js"), { force: true }),
|
|
1423
1436
|
rm(resolve(dirname(paths.runtime), "retained-context.js"), { force: true }),
|
|
1437
|
+
rm(resolve(dirname(paths.runtime), "retrieval-task.js"), { force: true }),
|
|
1438
|
+
rm(resolve(dirname(paths.runtime), "runtime-redaction.js"), { force: true }),
|
|
1439
|
+
rm(resolve(dirname(paths.runtime), "user-message.js"), { force: true }),
|
|
1424
1440
|
rm(resolve(dirname(paths.runtime), "approach-guidance.js"), { force: true }),
|
|
1441
|
+
rm(resolve(dirname(paths.runtime), "skill-guidance.js"), { force: true }),
|
|
1425
1442
|
rm(paths.runtimeContextFallback, { force: true }),
|
|
1426
1443
|
rm(paths.runtimeInvocationHealthWriter, { force: true }),
|
|
1427
1444
|
rm(paths.runtimeVersion, { force: true }),
|
|
@@ -1454,7 +1471,11 @@ async function installRuntime(paths) {
|
|
|
1454
1471
|
"image-bytes.js": imageBytes,
|
|
1455
1472
|
"image-capture.js": imageCapture,
|
|
1456
1473
|
"retained-context.js": await readFile(resolve(sourceDirectory, "retained-context.js"), "utf8"),
|
|
1474
|
+
"retrieval-task.js": (await readFile(resolve(sourceDirectory, "retrieval-task.js"), "utf8")).replaceAll("@lore-co/core/user-message", "./user-message.js"),
|
|
1475
|
+
"runtime-redaction.js": await readFile(resolve(sourceDirectory, "runtime-redaction.js"), "utf8"),
|
|
1476
|
+
"user-message.js": await readFile(fileURLToPath(import.meta.resolve("@lore-co/core/user-message")), "utf8"),
|
|
1457
1477
|
"approach-guidance.js": await readFile(resolve(sourceDirectory, "approach-guidance.js"), "utf8"),
|
|
1478
|
+
"skill-guidance.js": await readFile(resolve(sourceDirectory, "skill-guidance.js"), "utf8"),
|
|
1458
1479
|
"repository.js": repository,
|
|
1459
1480
|
"repository-address.js": await readFile(resolve(dirname(fileURLToPath(import.meta.resolve("@lore-co/core/repository-location"))), "repository-address.js"), "utf8"),
|
|
1460
1481
|
"directory-policy.js": (await readFile(fileURLToPath(import.meta.resolve("@lore-co/core/local-scope")), "utf8")).replaceAll("./repository-location.js", "./repository.js"),
|
|
@@ -1481,7 +1502,11 @@ async function installRuntime(paths) {
|
|
|
1481
1502
|
atomicWrite(resolve(dirname(paths.runtime), "image-bytes.js"), imageBytes, 0o600),
|
|
1482
1503
|
atomicWrite(resolve(dirname(paths.runtime), "image-capture.js"), imageCapture, 0o600),
|
|
1483
1504
|
atomicWrite(resolve(dirname(paths.runtime), "retained-context.js"), runtimeFiles["retained-context.js"], 0o600),
|
|
1505
|
+
atomicWrite(resolve(dirname(paths.runtime), "retrieval-task.js"), runtimeFiles["retrieval-task.js"], 0o600),
|
|
1506
|
+
atomicWrite(resolve(dirname(paths.runtime), "runtime-redaction.js"), runtimeFiles["runtime-redaction.js"], 0o600),
|
|
1507
|
+
atomicWrite(resolve(dirname(paths.runtime), "user-message.js"), runtimeFiles["user-message.js"], 0o600),
|
|
1484
1508
|
atomicWrite(resolve(dirname(paths.runtime), "approach-guidance.js"), runtimeFiles["approach-guidance.js"], 0o600),
|
|
1509
|
+
atomicWrite(resolve(dirname(paths.runtime), "skill-guidance.js"), runtimeFiles["skill-guidance.js"], 0o600),
|
|
1485
1510
|
atomicWrite(paths.runtimeRepository, repository, 0o600),
|
|
1486
1511
|
atomicWrite(resolve(dirname(paths.runtime), "repository-address.js"), runtimeFiles["repository-address.js"], 0o600),
|
|
1487
1512
|
atomicWrite(resolve(dirname(paths.runtime), "directory-policy.js"), runtimeFiles["directory-policy.js"], 0o600),
|
|
@@ -1555,7 +1580,21 @@ function parseConnectArguments(args) {
|
|
|
1555
1580
|
parsed.recovery = false;
|
|
1556
1581
|
continue;
|
|
1557
1582
|
}
|
|
1558
|
-
if (argument
|
|
1583
|
+
if (argument === "--current-project") {
|
|
1584
|
+
parsed.currentProject = true;
|
|
1585
|
+
continue;
|
|
1586
|
+
}
|
|
1587
|
+
if (argument === "--choose-folder") {
|
|
1588
|
+
parsed.chooseFolder = true;
|
|
1589
|
+
continue;
|
|
1590
|
+
}
|
|
1591
|
+
if (argument === "--all-projects") {
|
|
1592
|
+
parsed.allProjects = true;
|
|
1593
|
+
continue;
|
|
1594
|
+
}
|
|
1595
|
+
if (argument !== "--repository" &&
|
|
1596
|
+
argument !== "--folder" &&
|
|
1597
|
+
argument !== "--name" &&
|
|
1559
1598
|
argument !== "--url" &&
|
|
1560
1599
|
argument !== "--dashboard-url" &&
|
|
1561
1600
|
argument !== "--token" &&
|
|
@@ -1566,7 +1605,13 @@ function parseConnectArguments(args) {
|
|
|
1566
1605
|
}
|
|
1567
1606
|
const [value, valueIndex] = valueAfter(args, index, argument);
|
|
1568
1607
|
index = valueIndex;
|
|
1569
|
-
if (argument === "--
|
|
1608
|
+
if (argument === "--repository") {
|
|
1609
|
+
parsed.repository = value;
|
|
1610
|
+
}
|
|
1611
|
+
else if (argument === "--folder") {
|
|
1612
|
+
(parsed.folders ??= []).push(value);
|
|
1613
|
+
}
|
|
1614
|
+
else if (argument === "--name") {
|
|
1570
1615
|
parsed.connectionName = value;
|
|
1571
1616
|
}
|
|
1572
1617
|
else if (argument === "--fallback") {
|
|
@@ -1597,6 +1642,7 @@ function parseConnectArguments(args) {
|
|
|
1597
1642
|
throw new Error("--agent must be claude, codex, copilot, copilot-cli, copilot-vscode, cowork, cursor, opencode, polytoken, or t3code");
|
|
1598
1643
|
}
|
|
1599
1644
|
}
|
|
1645
|
+
validateConnectProjectOptions(parsed);
|
|
1600
1646
|
if (parsed.login && parsed.token !== undefined) {
|
|
1601
1647
|
throw new Error("--login and --token cannot be used together");
|
|
1602
1648
|
}
|
|
@@ -1661,7 +1707,8 @@ async function connectWithCredentialLocked(options, identity) {
|
|
|
1661
1707
|
? existing.apiUrl === apiUrl && existing.token === token ? identity
|
|
1662
1708
|
: await authenticatedIdentity(existing.apiUrl, existing.token, timeoutMs).catch(() => undefined)
|
|
1663
1709
|
: undefined;
|
|
1664
|
-
const
|
|
1710
|
+
const directories = await captureDirectories(options, paths.home, options.cwd);
|
|
1711
|
+
const connection = await prepareConnection(paths, identity, { apiUrl, token, ...(directories === undefined ? {} : { directories }), ...(options.connectionName ? { connectionName: options.connectionName } : {}) }, previousIdentity);
|
|
1665
1712
|
await secureWindowsDirectory(paths.loreDirectory);
|
|
1666
1713
|
const recoveryEnv = options.home === undefined ? process.env : { ...process.env, ZDOTDIR: paths.home };
|
|
1667
1714
|
let recoveryWarning;
|
|
@@ -1708,6 +1755,31 @@ async function connectWithCredentialLocked(options, identity) {
|
|
|
1708
1755
|
cursorMcpDocuments.set(mcpPath, { document: mcp, merged: mergeLoreCursorMcp(mcp.exists ? mcp.value : {}, paths) });
|
|
1709
1756
|
}
|
|
1710
1757
|
}
|
|
1758
|
+
const agentConfigPaths = {};
|
|
1759
|
+
for (const agent of agents) {
|
|
1760
|
+
agentConfigPaths[agent] = installations
|
|
1761
|
+
.filter((installation) => installation.agent === agent)
|
|
1762
|
+
.map((installation) => installation.configPath);
|
|
1763
|
+
}
|
|
1764
|
+
const config = {
|
|
1765
|
+
...connection.fields,
|
|
1766
|
+
version: 2,
|
|
1767
|
+
apiUrl,
|
|
1768
|
+
...(dashboardUrl === undefined ? {} : { dashboardUrl }),
|
|
1769
|
+
workspaceId: identity.workspaceId,
|
|
1770
|
+
token: token.trim(),
|
|
1771
|
+
agents,
|
|
1772
|
+
agentConfigPaths,
|
|
1773
|
+
connectedAt: connection.profiles.find(value => value.connectionId === connection.fields.connectionId)?.connectedAt ?? now.toISOString(),
|
|
1774
|
+
timeoutMs,
|
|
1775
|
+
};
|
|
1776
|
+
const reliabilityStore = new ReliabilityStore(identity.workspaceId, {
|
|
1777
|
+
home: paths.home,
|
|
1778
|
+
connectionId: config.connectionId,
|
|
1779
|
+
});
|
|
1780
|
+
await reliabilityStore.initialize();
|
|
1781
|
+
// Folder restrictions must be durable before any new hook can run.
|
|
1782
|
+
await persistConnection(paths, config, connection.profiles);
|
|
1711
1783
|
if (installations.some((installation) => targetFor(installation.agent).runtimeRequired)) {
|
|
1712
1784
|
await installRuntime(paths);
|
|
1713
1785
|
}
|
|
@@ -1735,30 +1807,6 @@ async function connectWithCredentialLocked(options, identity) {
|
|
|
1735
1807
|
backups.push(result.backup);
|
|
1736
1808
|
}
|
|
1737
1809
|
}
|
|
1738
|
-
const agentConfigPaths = {};
|
|
1739
|
-
for (const agent of agents) {
|
|
1740
|
-
agentConfigPaths[agent] = installations
|
|
1741
|
-
.filter((installation) => installation.agent === agent)
|
|
1742
|
-
.map((installation) => installation.configPath);
|
|
1743
|
-
}
|
|
1744
|
-
const config = {
|
|
1745
|
-
...connection.fields,
|
|
1746
|
-
version: 2,
|
|
1747
|
-
apiUrl,
|
|
1748
|
-
...(dashboardUrl === undefined ? {} : { dashboardUrl }),
|
|
1749
|
-
workspaceId: identity.workspaceId,
|
|
1750
|
-
token: token.trim(),
|
|
1751
|
-
agents,
|
|
1752
|
-
agentConfigPaths,
|
|
1753
|
-
connectedAt: connection.profiles.find(value => value.connectionId === connection.fields.connectionId)?.connectedAt ?? now.toISOString(),
|
|
1754
|
-
timeoutMs,
|
|
1755
|
-
};
|
|
1756
|
-
const reliabilityStore = new ReliabilityStore(identity.workspaceId, {
|
|
1757
|
-
home: paths.home,
|
|
1758
|
-
connectionId: config.connectionId,
|
|
1759
|
-
});
|
|
1760
|
-
await reliabilityStore.initialize();
|
|
1761
|
-
await persistConnection(paths, config, connection.profiles);
|
|
1762
1810
|
if (existing && !existing.connectionId && existing.apiUrl === apiUrl && existing.token === token) {
|
|
1763
1811
|
await new ReliabilityStore(identity.workspaceId, { home: paths.home }).transferPendingTo(reliabilityStore);
|
|
1764
1812
|
await reliabilityStore.migrateLegacyQueue(paths.queue);
|
|
@@ -1778,7 +1826,10 @@ async function connectWithCredentialLocked(options, identity) {
|
|
|
1778
1826
|
.catch((error) => [`Host recovery setup: ${error.message}`]) : [];
|
|
1779
1827
|
if (options.recovery === false)
|
|
1780
1828
|
await disableRecovery(paths.home);
|
|
1829
|
+
const skills = await installLoreSkill(paths, installations);
|
|
1781
1830
|
return {
|
|
1831
|
+
capture: { folders: config.directories?.include ?? null, excludedFolders: config.directories?.exclude ?? [] },
|
|
1832
|
+
skillFiles: skills.files,
|
|
1782
1833
|
connected: true,
|
|
1783
1834
|
apiUrl: config.apiUrl,
|
|
1784
1835
|
identity,
|
|
@@ -1786,7 +1837,7 @@ async function connectWithCredentialLocked(options, identity) {
|
|
|
1786
1837
|
config: paths.config,
|
|
1787
1838
|
changedHookFiles,
|
|
1788
1839
|
backups,
|
|
1789
|
-
warnings: [...(connection.needsFolders ? [`Lore is off for ${config.connectionName} until you
|
|
1840
|
+
warnings: [...skills.warnings, ...(connection.needsFolders ? [`Lore is off for ${config.connectionName} until you choose where to record. Reconnect with --folder <path> or --all-projects, or run lore config open --connection ${config.connectionName}.`] : []), ...requestedExpansion.warnings, ...hostRecoveryWarnings, ...(agents.includes("codex")
|
|
1790
1841
|
? ["Codex requires hook approval. Open /hooks in Codex and review any new or changed Lore hooks, then start a fresh session. Run lore doctor to verify approval and the first invocation."]
|
|
1791
1842
|
: [])],
|
|
1792
1843
|
...(recoveryNotice ? { recoveryNotice } : {}),
|
|
@@ -1940,6 +1991,7 @@ async function connectCommand(args) {
|
|
|
1940
1991
|
if (parsed.login && hasProvidedToken) {
|
|
1941
1992
|
throw new Error("--login cannot be combined with an explicit or environment workspace token. Unset it or use the token directly.");
|
|
1942
1993
|
}
|
|
1994
|
+
const capture = await resolveConnectProject(parsed, paths.home);
|
|
1943
1995
|
const authorization = parsed.login
|
|
1944
1996
|
? await requestDeviceAuthorization({
|
|
1945
1997
|
apiUrl,
|
|
@@ -1953,6 +2005,7 @@ async function connectCommand(args) {
|
|
|
1953
2005
|
throw new Error("Workspace token is required. Use --login, --token <token>, LORE_WORKSPACE_TOKEN, or LORE_TOKEN.");
|
|
1954
2006
|
}
|
|
1955
2007
|
const result = await connectWithCredential({
|
|
2008
|
+
...capture,
|
|
1956
2009
|
...(parsed.connectionName === undefined ? {} : { connectionName: parsed.connectionName }),
|
|
1957
2010
|
...(parsed.fallback === undefined ? {} : { fallback: parsed.fallback }),
|
|
1958
2011
|
recovery: parsed.recovery ?? true,
|
|
@@ -1964,7 +2017,9 @@ async function connectCommand(args) {
|
|
|
1964
2017
|
});
|
|
1965
2018
|
if (authorization)
|
|
1966
2019
|
await acknowledgeDeviceAuthorization(apiUrl, authorization);
|
|
1967
|
-
|
|
2020
|
+
const captureSummary = result.capture.folders === null ? "all projects allowed by the workspace"
|
|
2021
|
+
: result.capture.folders.length ? result.capture.folders.join(", ") : "paused — choose folders with --folder <path>";
|
|
2022
|
+
writeResult(result, parsed.json, `access authorized; integrations installed: ${result.agents.join(", ")}\napi_url: ${result.apiUrl}\nconfig: ${result.config}\ncapture: ${captureSummary}${result.capture.excludedFolders.length ? `; excluded: ${result.capture.excludedFolders.join(", ")}` : ""}\nRestart your agent and complete a turn, then run lore doctor to verify recording.\n${result.skillFiles.length ? 'Choose lore in your agent’s skills to find knowledge or remember this session.\n' : ''}${result.recoveryNotice ? `${result.recoveryNotice}\n` : ""}${result.warnings.map((warning) => `warning: ${warning}\n`).join("")}`);
|
|
1968
2023
|
}
|
|
1969
2024
|
async function queueCount(paths) {
|
|
1970
2025
|
try {
|
|
@@ -2052,7 +2107,11 @@ async function inspectRuntimeInstallation(required, paths) {
|
|
|
2052
2107
|
"image-bytes.js": resolve(dirname(paths.runtime), "image-bytes.js"),
|
|
2053
2108
|
"image-capture.js": resolve(dirname(paths.runtime), "image-capture.js"),
|
|
2054
2109
|
"retained-context.js": resolve(dirname(paths.runtime), "retained-context.js"),
|
|
2110
|
+
"retrieval-task.js": resolve(dirname(paths.runtime), "retrieval-task.js"),
|
|
2111
|
+
"runtime-redaction.js": resolve(dirname(paths.runtime), "runtime-redaction.js"),
|
|
2112
|
+
"user-message.js": resolve(dirname(paths.runtime), "user-message.js"),
|
|
2055
2113
|
"approach-guidance.js": resolve(dirname(paths.runtime), "approach-guidance.js"),
|
|
2114
|
+
"skill-guidance.js": resolve(dirname(paths.runtime), "skill-guidance.js"),
|
|
2056
2115
|
"repository.js": paths.runtimeRepository,
|
|
2057
2116
|
"repository-address.js": resolve(dirname(paths.runtime), "repository-address.js"),
|
|
2058
2117
|
"directory-policy.js": resolve(dirname(paths.runtime), "directory-policy.js"),
|
|
@@ -2238,8 +2297,18 @@ async function getAgentStatus(agent, config, paths, runtime) {
|
|
|
2238
2297
|
invocationError: invocation.error,
|
|
2239
2298
|
};
|
|
2240
2299
|
}
|
|
2300
|
+
// Diagnostics remain available when the current folder has capture disabled.
|
|
2301
|
+
// A fallback reads only the last saved connection; it never enables capture.
|
|
2302
|
+
async function diagnosticConfig(paths, cwd) {
|
|
2303
|
+
try {
|
|
2304
|
+
return await readConnectorConfig(paths, cwd);
|
|
2305
|
+
}
|
|
2306
|
+
catch {
|
|
2307
|
+
return readConnectorConfig(paths);
|
|
2308
|
+
}
|
|
2309
|
+
}
|
|
2241
2310
|
async function statusData(paths, cwd) {
|
|
2242
|
-
const config = await
|
|
2311
|
+
const config = await diagnosticConfig(paths, cwd);
|
|
2243
2312
|
let configMode = null;
|
|
2244
2313
|
try {
|
|
2245
2314
|
const metadata = await stat(paths.config);
|
|
@@ -2256,6 +2325,7 @@ async function statusData(paths, cwd) {
|
|
|
2256
2325
|
Promise.all(CONFIGURED_AGENT_NAMES.map(async (agent) => getAgentStatus(agent, config, paths, runtime))),
|
|
2257
2326
|
]);
|
|
2258
2327
|
return {
|
|
2328
|
+
folderAccess: await checkDirectory(cwd, paths.home, config ?? undefined),
|
|
2259
2329
|
schemaVersion: "lore-cli-status-v1",
|
|
2260
2330
|
integrationContractVersion: RELIABILITY_INTEGRATION_CONTRACT_VERSION,
|
|
2261
2331
|
connected: config !== null,
|
|
@@ -2290,7 +2360,7 @@ async function statusCommand(args) {
|
|
|
2290
2360
|
const metricRate = (value) => value === null || value === undefined
|
|
2291
2361
|
? "-"
|
|
2292
2362
|
: `${(value * 100).toFixed(1)}%`;
|
|
2293
|
-
writeResult(data, parsed.json, `connected: ${data.connected ? "yes" : "no"}\napi_url: ${data.apiUrl ?? "-"}\nconfig_mode: ${data.configMode ?? "-"}\nruntime: ${data.runtimeRequired ? (data.runtimeInstalled ? `installed (${data.runtimeVersion})` : data.runtimeVersion === null ? "missing" : `stale (${data.runtimeVersion})`) : "not required"}\ndurable_outbox: ${data.reliability?.outbox.total ?? 0} ready=${data.reliability?.outbox.ready ?? 0} auth_blocked=${data.reliability?.outbox.authBlocked ?? 0} dead=${data.reliability?.outbox.dead ?? 0}\noldest_capture: ${data.reliability?.outbox.oldestEnqueuedAt ?? "-"}\ncontext_snapshots: ${data.reliability?.cache.context ?? 0}\noldest_context_snapshot: ${data.reliability?.cache.oldestContextWrittenAt ?? "-"}\npolicy_snapshots: ${data.reliability?.cache.policy ?? 0}\nlocal_context_fallback_rate: ${metricRate(data.reliability?.operational.retrieval.fallbackRate)}\nlocal_guard_coverage: ${metricRate(data.reliability?.operational.guard.coverageRate)}\nlocal_guard_failures: ${data.reliability?.operational.guard.failures ?? 0}\nlocal_retrieval_failures: ${data.reliability?.operational.retrieval.failed ?? 0}\n${data.reliabilityError === null ? "" : `reliability_error: ${data.reliabilityError}\n`}${agentLines}\n${externalSurfaceLines}\n`);
|
|
2363
|
+
writeResult(data, parsed.json, `connected: ${data.connected ? "yes" : "no"}\ncurrent_folder: ${data.folderAccess.allowed ? "allowed" : "off"} (${data.folderAccess.reason})\napi_url: ${data.apiUrl ?? "-"}\nconfig_mode: ${data.configMode ?? "-"}\nruntime: ${data.runtimeRequired ? (data.runtimeInstalled ? `installed (${data.runtimeVersion})` : data.runtimeVersion === null ? "missing" : `stale (${data.runtimeVersion})`) : "not required"}\ndurable_outbox: ${data.reliability?.outbox.total ?? 0} ready=${data.reliability?.outbox.ready ?? 0} auth_blocked=${data.reliability?.outbox.authBlocked ?? 0} dead=${data.reliability?.outbox.dead ?? 0}\noldest_capture: ${data.reliability?.outbox.oldestEnqueuedAt ?? "-"}\ncontext_snapshots: ${data.reliability?.cache.context ?? 0}\noldest_context_snapshot: ${data.reliability?.cache.oldestContextWrittenAt ?? "-"}\npolicy_snapshots: ${data.reliability?.cache.policy ?? 0}\nlocal_context_fallback_rate: ${metricRate(data.reliability?.operational.retrieval.fallbackRate)}\nlocal_guard_coverage: ${metricRate(data.reliability?.operational.guard.coverageRate)}\nlocal_guard_failures: ${data.reliability?.operational.guard.failures ?? 0}\nlocal_retrieval_failures: ${data.reliability?.operational.retrieval.failed ?? 0}\n${data.reliabilityError === null ? "" : `reliability_error: ${data.reliabilityError}\n`}${agentLines}\n${externalSurfaceLines}\n`);
|
|
2294
2364
|
}
|
|
2295
2365
|
async function disconnectCommand(args) {
|
|
2296
2366
|
const parsed = parseOutputArguments(args, DISCONNECT_HELP, "disconnect");
|
|
@@ -2336,6 +2406,7 @@ export async function disconnectInstallation(paths = getLorePaths(), preservePen
|
|
|
2336
2406
|
backups.push(result.backup);
|
|
2337
2407
|
}
|
|
2338
2408
|
}
|
|
2409
|
+
await removeLoreSkill(paths, installations);
|
|
2339
2410
|
await Promise.all([
|
|
2340
2411
|
rm(paths.config, { force: true }),
|
|
2341
2412
|
rm(resolve(paths.loreDirectory, "connections"), { recursive: true, force: true }),
|
|
@@ -2351,6 +2422,10 @@ export async function disconnectInstallation(paths = getLorePaths(), preservePen
|
|
|
2351
2422
|
rm(resolve(dirname(paths.runtime), "image-bytes.js"), { force: true }),
|
|
2352
2423
|
rm(resolve(dirname(paths.runtime), "image-capture.js"), { force: true }),
|
|
2353
2424
|
rm(resolve(dirname(paths.runtime), "retained-context.js"), { force: true }),
|
|
2425
|
+
rm(resolve(dirname(paths.runtime), "retrieval-task.js"), { force: true }),
|
|
2426
|
+
rm(resolve(dirname(paths.runtime), "runtime-redaction.js"), { force: true }),
|
|
2427
|
+
rm(resolve(dirname(paths.runtime), "user-message.js"), { force: true }),
|
|
2428
|
+
rm(resolve(dirname(paths.runtime), "skill-guidance.js"), { force: true }),
|
|
2354
2429
|
rm(paths.runtimeInvocationHealthWriter, { force: true }),
|
|
2355
2430
|
rm(paths.runtimeVersion, { force: true }),
|
|
2356
2431
|
rm(paths.runtimePackage, { force: true }),
|
|
@@ -2475,9 +2550,9 @@ async function doctorCommand(args) {
|
|
|
2475
2550
|
return;
|
|
2476
2551
|
}
|
|
2477
2552
|
const paths = getLorePaths();
|
|
2478
|
-
const config = await
|
|
2553
|
+
const config = await diagnosticConfig(paths, process.cwd());
|
|
2479
2554
|
const status = await statusData(paths, process.cwd());
|
|
2480
|
-
const checks = [];
|
|
2555
|
+
const checks = [{ name: "capture-folder", status: status.folderAccess.allowed ? "ok" : "warning", detail: status.folderAccess.allowed ? status.folderAccess.reason : `Recording is off here: ${status.folderAccess.reason}. Run lore scope check <folder> to verify a selected folder.` }];
|
|
2481
2556
|
checks.push({
|
|
2482
2557
|
name: "platform",
|
|
2483
2558
|
status: platform() === "darwin" || platform() === "linux" || isWindows() ? "ok" : "error",
|
|
@@ -2664,6 +2739,9 @@ async function printCommandHelp(path) {
|
|
|
2664
2739
|
case "approach":
|
|
2665
2740
|
await runApproachCommand(args, null);
|
|
2666
2741
|
return;
|
|
2742
|
+
case "skill":
|
|
2743
|
+
await runSkillCommand(args, null);
|
|
2744
|
+
return;
|
|
2667
2745
|
case "guard":
|
|
2668
2746
|
await runGuardCommand(args, null);
|
|
2669
2747
|
return;
|
|
@@ -2752,8 +2830,8 @@ async function executeCli(args = process.argv.slice(2)) {
|
|
|
2752
2830
|
return;
|
|
2753
2831
|
}
|
|
2754
2832
|
const commandArgs = args.slice(1);
|
|
2755
|
-
if (["ask", "remember", "share", "resume", "continue", "approach"].includes(command)) {
|
|
2756
|
-
const decision = await checkDirectory(process.cwd(), getLorePaths(
|
|
2833
|
+
if (["ask", "remember", "share", "resume", "continue", "approach", "skill"].includes(command) && !(command === "skill" && commandArgs[0] === "discover")) {
|
|
2834
|
+
const decision = await checkDirectory(process.cwd(), getLorePaths(["approach", "skill"].includes(command) ? process.env.LORE_HOME : undefined).home);
|
|
2757
2835
|
if (!decision.allowed)
|
|
2758
2836
|
throw new Error(`Lore is off in this folder. ${decision.reason}`);
|
|
2759
2837
|
}
|
|
@@ -2798,6 +2876,9 @@ async function executeCli(args = process.argv.slice(2)) {
|
|
|
2798
2876
|
case "approach":
|
|
2799
2877
|
await runApproachCommand(commandArgs, await readConnectorConfig(getLorePaths(process.env.LORE_HOME), process.cwd()));
|
|
2800
2878
|
return;
|
|
2879
|
+
case "skill":
|
|
2880
|
+
await runSkillCommand(commandArgs, commandArgs[0] === "discover" ? null : await readConnectorConfig(getLorePaths(process.env.LORE_HOME), process.cwd()));
|
|
2881
|
+
return;
|
|
2801
2882
|
case "guard":
|
|
2802
2883
|
await runGuardCommand(commandArgs, await readConnectorConfig(getLorePaths(), process.cwd()));
|
|
2803
2884
|
return;
|
|
@@ -2863,6 +2944,7 @@ async function executeCli(args = process.argv.slice(2)) {
|
|
|
2863
2944
|
});
|
|
2864
2945
|
return {
|
|
2865
2946
|
agents: connected.agents,
|
|
2947
|
+
warnings: connected.warnings,
|
|
2866
2948
|
verified: await verifyConnectedInstallation(),
|
|
2867
2949
|
};
|
|
2868
2950
|
},
|