knodin 0.8.6 → 0.8.7
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 +6 -0
- package/dist/bin/cli.js +153 -11
- package/dist/bin/launcher.js +0 -0
- package/dist/src/cli-model.js +31 -1
- package/dist/src/init.js +16 -0
- package/dist/src/repository-management.js +219 -3
- package/dist/src/skill-management.js +149 -0
- package/dist/src/system-config.js +176 -16
- package/dist/src/system-management.js +508 -0
- package/dist/src/tools/knodin-tools.js +108 -15
- package/docs/CLI.md +7 -0
- package/docs/SYSTEMS-AND-RELATIONSHIPS.md +27 -6
- package/docs/prompts/declare-multi-repository-system.md +18 -0
- package/docs/releases/0.8.7.md +27 -0
- package/package.json +5 -2
- package/skills/knodin-debug/SKILL.md +12 -0
- package/skills/knodin-debug/agents/openai.yaml +4 -0
- package/skills/knodin-explore/SKILL.md +11 -0
- package/skills/knodin-explore/agents/openai.yaml +4 -0
- package/skills/knodin-impact/SKILL.md +11 -0
- package/skills/knodin-impact/agents/openai.yaml +4 -0
- package/skills/knodin-lifecycle/SKILL.md +12 -0
- package/skills/knodin-lifecycle/agents/openai.yaml +4 -0
- package/skills/knodin-refactor/SKILL.md +12 -0
- package/skills/knodin-refactor/agents/openai.yaml +4 -0
- package/skills/knodin-review/SKILL.md +11 -0
- package/skills/knodin-review/agents/openai.yaml +4 -0
- package/skills/knodin-systems/SKILL.md +14 -0
- package/skills/knodin-systems/agents/openai.yaml +4 -0
|
@@ -35,7 +35,8 @@ import { discoverRepositories, initializeRepositories, inventoryRepository, sear
|
|
|
35
35
|
import { applyResponseBudget } from "../response-budget.js";
|
|
36
36
|
import { loadSharedIndexConfig } from "../shared-index/config.js";
|
|
37
37
|
import { EMPTY_OVERLAY, readSharedIndexProvenance, readSharedRestoreAttempt, } from "../shared-index/provenance.js";
|
|
38
|
-
import { configuredRepositoryInitMemoryLimitBytes, enrichSystemRelationships, incorporateSystemQueryEvidence, indexModeForPath, loadSystemConfiguration, queryConfiguredSystem, systemMembershipsForPath, validateSystemHealth, } from "../system-config.js";
|
|
38
|
+
import { configuredRepositoryInitMemoryLimitBytes, enrichSystemRelationships, incorporateSystemQueryEvidence, indexModeForPath, loadSystemConfiguration, queryConfiguredSystem, RELATIONSHIP_TYPES, systemMembershipsForPath, validateSystemHealth, } from "../system-config.js";
|
|
39
|
+
import { applySystemPlan, planSystemImport, planSystemLink, planSystemRelate, planSystemUnlink, planSystemUnrelate, } from "../system-management.js";
|
|
39
40
|
import { trustedUpdateStatus } from "../update-policy.js";
|
|
40
41
|
import { waitForFresh } from "../wait-for-fresh.js";
|
|
41
42
|
import { inspectWorktrees, reconcileWorktrees, removeManagedWorktree, } from "../worktree-lifecycle.js";
|
|
@@ -317,7 +318,7 @@ function buildDocumentedKnodinTools() {
|
|
|
317
318
|
},
|
|
318
319
|
from: {
|
|
319
320
|
type: "string",
|
|
320
|
-
description: "review: older ref of
|
|
321
|
+
description: "review: older ref of a revision pair; system relate/unrelate: source component id.",
|
|
321
322
|
},
|
|
322
323
|
toRevision: {
|
|
323
324
|
type: "string",
|
|
@@ -494,9 +495,30 @@ function buildDocumentedKnodinTools() {
|
|
|
494
495
|
},
|
|
495
496
|
systemAction: {
|
|
496
497
|
type: "string",
|
|
497
|
-
enum: [
|
|
498
|
-
|
|
498
|
+
enum: [
|
|
499
|
+
"list",
|
|
500
|
+
"show",
|
|
501
|
+
"validate",
|
|
502
|
+
"query",
|
|
503
|
+
"link",
|
|
504
|
+
"relate",
|
|
505
|
+
"unlink",
|
|
506
|
+
"unrelate",
|
|
507
|
+
"import",
|
|
508
|
+
],
|
|
499
509
|
},
|
|
510
|
+
planDigest: {
|
|
511
|
+
type: "string",
|
|
512
|
+
description: "system writes: digest returned by the approved preview",
|
|
513
|
+
},
|
|
514
|
+
repositories: { type: "array", items: { type: "string" } },
|
|
515
|
+
scope: { type: "string", enum: ["personal", "team"] },
|
|
516
|
+
distributed: { type: "boolean" },
|
|
517
|
+
repositoryIds: { type: "object", additionalProperties: { type: "string" } },
|
|
518
|
+
components: { type: "object", additionalProperties: { type: "object" } },
|
|
519
|
+
evidence: { type: "string" },
|
|
520
|
+
relationshipType: { type: "string", enum: RELATIONSHIP_TYPES },
|
|
521
|
+
requireComplete: { type: "boolean" },
|
|
500
522
|
repositoryAction: {
|
|
501
523
|
type: "string",
|
|
502
524
|
enum: ["discover", "init", "status", "doctor", "search"],
|
|
@@ -731,14 +753,14 @@ const RESPONSE_DEFAULTS = {
|
|
|
731
753
|
"diagnostics:archive": { bytes: 65_536, tokens: 16_384, items: 100 },
|
|
732
754
|
default: { bytes: 65_536, tokens: 16_384, items: 100 },
|
|
733
755
|
};
|
|
734
|
-
async function populateRepositoryDiagnoses(records, repositories
|
|
756
|
+
async function populateRepositoryDiagnoses(records, repositories) {
|
|
735
757
|
repositories.length = 0;
|
|
736
758
|
for (const record of records) {
|
|
737
759
|
try {
|
|
738
760
|
const graph = attachLifecycleHealth(record.path, await engine.status(record.path, { audit: "deep" }));
|
|
739
761
|
const repository = await inventoryRepository(record, {
|
|
740
762
|
status: async () => graph,
|
|
741
|
-
systemMemberships: (target) => systemMembershipsForPath(loadSystemConfiguration(
|
|
763
|
+
systemMemberships: (target) => systemMembershipsForPath(loadSystemConfiguration(target), target),
|
|
742
764
|
});
|
|
743
765
|
repositories.push({
|
|
744
766
|
...repository,
|
|
@@ -770,12 +792,11 @@ async function handleRepositoriesOperation(options) {
|
|
|
770
792
|
};
|
|
771
793
|
const inventory = async () => {
|
|
772
794
|
const discovery = await discoverRepositories(discoveryRoots, discoveryOptions);
|
|
773
|
-
const systemConfig = loadSystemConfiguration(discoveryRoots[0] ?? repo);
|
|
774
795
|
const repositories = [];
|
|
775
796
|
for (const record of discovery.repositories) {
|
|
776
797
|
repositories.push(await inventoryRepository(record, {
|
|
777
798
|
status: async (target) => attachLifecycleHealth(target, await engine.status(target, { audit: "cached" })),
|
|
778
|
-
systemMemberships: (target) => systemMembershipsForPath(
|
|
799
|
+
systemMemberships: (target) => systemMembershipsForPath(loadSystemConfiguration(target), target),
|
|
779
800
|
}));
|
|
780
801
|
}
|
|
781
802
|
return { discovery, repositories };
|
|
@@ -792,7 +813,7 @@ async function handleRepositoriesOperation(options) {
|
|
|
792
813
|
worktrees: linkedWorktrees,
|
|
793
814
|
dryRun,
|
|
794
815
|
manifestPath,
|
|
795
|
-
indexMode: (target) => indexModeForPath(
|
|
816
|
+
indexMode: (target) => indexModeForPath(loadSystemConfiguration(target), target),
|
|
796
817
|
isolatedInitialize: (target) => runRepositoryInitializationProcess({ repository: target, command, memoryLimitBytes }),
|
|
797
818
|
});
|
|
798
819
|
const { repositories } = await inventory();
|
|
@@ -801,7 +822,6 @@ async function handleRepositoriesOperation(options) {
|
|
|
801
822
|
if (repositoryAction === "search") {
|
|
802
823
|
if (!query?.trim())
|
|
803
824
|
throw new Error("knodin repositories search requires a non-empty `query`");
|
|
804
|
-
const systemConfig = loadSystemConfiguration(discoveryRoots[0] ?? repo);
|
|
805
825
|
return searchRepositories(discoveryRoots, query, {
|
|
806
826
|
...discoveryOptions,
|
|
807
827
|
include,
|
|
@@ -817,12 +837,12 @@ async function handleRepositoriesOperation(options) {
|
|
|
817
837
|
includeSource: true,
|
|
818
838
|
federate: false,
|
|
819
839
|
}),
|
|
820
|
-
systemMemberships: (target) => systemMembershipsForPath(
|
|
840
|
+
systemMemberships: (target) => systemMembershipsForPath(loadSystemConfiguration(target), target),
|
|
821
841
|
});
|
|
822
842
|
}
|
|
823
843
|
const { discovery, repositories } = await inventory();
|
|
824
844
|
if (repositoryAction === "doctor")
|
|
825
|
-
await populateRepositoryDiagnoses(discovery.repositories, repositories
|
|
845
|
+
await populateRepositoryDiagnoses(discovery.repositories, repositories);
|
|
826
846
|
return bounded({
|
|
827
847
|
schemaVersion: 1,
|
|
828
848
|
linkedWorktrees: discoveryOptions.linkedWorktrees,
|
|
@@ -833,7 +853,67 @@ async function handleRepositoriesOperation(options) {
|
|
|
833
853
|
}, `repositories:${repositoryAction}`);
|
|
834
854
|
}
|
|
835
855
|
async function handleSystemOperation(options) {
|
|
836
|
-
const { systemAction, symbol, repo,
|
|
856
|
+
const { systemAction, symbol, repo, bounded } = options;
|
|
857
|
+
if (["link", "relate", "unlink", "unrelate", "import"].includes(systemAction)) {
|
|
858
|
+
if (systemAction !== "import" && !symbol)
|
|
859
|
+
throw new Error(`knodin system ${systemAction} requires \`symbol\``);
|
|
860
|
+
const systemId = symbol ?? "";
|
|
861
|
+
let plan;
|
|
862
|
+
if (systemAction === "import") {
|
|
863
|
+
if (!options.manifestPath)
|
|
864
|
+
throw new Error("system import requires manifestPath");
|
|
865
|
+
plan = planSystemImport({
|
|
866
|
+
manifestPath: options.manifestPath,
|
|
867
|
+
scope: options.scope,
|
|
868
|
+
repoPath: repo,
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
else if (systemAction === "link")
|
|
872
|
+
plan = planSystemLink({
|
|
873
|
+
systemId,
|
|
874
|
+
repositories: options.repositories ?? [],
|
|
875
|
+
scope: options.scope,
|
|
876
|
+
distributed: options.distributed,
|
|
877
|
+
repositoryIds: options.repositoryIds,
|
|
878
|
+
components: options.components,
|
|
879
|
+
});
|
|
880
|
+
else if (systemAction === "relate") {
|
|
881
|
+
if (!options.relationshipType || !options.from || !options.to || !options.evidence)
|
|
882
|
+
throw new Error("system relate requires relationshipType, from, to, and evidence");
|
|
883
|
+
plan = planSystemRelate({
|
|
884
|
+
systemId,
|
|
885
|
+
type: options.relationshipType,
|
|
886
|
+
from: options.from,
|
|
887
|
+
to: options.to,
|
|
888
|
+
evidence: options.evidence,
|
|
889
|
+
repoPath: repo,
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
else if (systemAction === "unlink")
|
|
893
|
+
plan = planSystemUnlink({
|
|
894
|
+
systemId,
|
|
895
|
+
repositories: options.repositories,
|
|
896
|
+
repoPath: repo,
|
|
897
|
+
});
|
|
898
|
+
else {
|
|
899
|
+
if (!options.relationshipType || !options.from || !options.to)
|
|
900
|
+
throw new Error("system unrelate requires relationshipType, from, and to");
|
|
901
|
+
plan = planSystemUnrelate({
|
|
902
|
+
systemId,
|
|
903
|
+
type: options.relationshipType,
|
|
904
|
+
from: options.from,
|
|
905
|
+
to: options.to,
|
|
906
|
+
repoPath: repo,
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
if (options.apply === true) {
|
|
910
|
+
if (!options.planDigest)
|
|
911
|
+
throw new Error("system writes require planDigest from an approved preview");
|
|
912
|
+
if (options.planDigest !== plan.planDigest)
|
|
913
|
+
throw new Error("system plan changed after preview; preview again");
|
|
914
|
+
}
|
|
915
|
+
return bounded(options.apply === true ? applySystemPlan(plan) : plan, `system:${systemAction}`);
|
|
916
|
+
}
|
|
837
917
|
const config = await enrichSystemRelationships(loadSystemConfiguration(repo));
|
|
838
918
|
if (systemAction === "list") {
|
|
839
919
|
return bounded({
|
|
@@ -859,7 +939,7 @@ async function handleSystemOperation(options) {
|
|
|
859
939
|
const validation = await validateSystemHealth(config, symbol, async (target) => attachLifecycleHealth(target, await engine.status(target, { audit: "cached" })), repo);
|
|
860
940
|
if (systemAction === "validate")
|
|
861
941
|
return bounded({ systemId: symbol, ...validation }, "system:validate");
|
|
862
|
-
return bounded(queryConfiguredSystem(config, symbol,
|
|
942
|
+
return bounded(queryConfiguredSystem(config, symbol, options.requireComplete === true, validation), "system:query");
|
|
863
943
|
}
|
|
864
944
|
async function handlePullRequestsOperation(options) {
|
|
865
945
|
const { repo, engine, limit, prNumber, prState, branches, auditRange, auditBase, auditHead, expectedLogin, } = options;
|
|
@@ -1296,7 +1376,7 @@ async function handleDiagnosticsOperation(repo, args, bounded) {
|
|
|
1296
1376
|
async function dispatchKnodinTool(args) {
|
|
1297
1377
|
const startedAt = performance.now();
|
|
1298
1378
|
const parsedArgs = (args ?? {});
|
|
1299
|
-
const { operation, symbol, base, diffScope, from, toRevision, reviewFiles, query, pattern, to, limit, depth, impactMode, direction, relationKinds, minConfidence, includeTests, includeDataFlow, flowVariable, apply, force, detailLevel, prNumber, prState, branches, auditRange, auditBase, auditHead, expectedLogin, worktreeAction, worktreePath, telemetryAction, telemetryRetentionDays, task, changedFiles, repoPath, section, systemAction, repositoryAction, roots, linkedWorktrees, cursor, allowPartial, dryRun, manifestPath, identity, file, kind, toIdentity, toFile, toKind, byteBudget, tokenBudget, itemBudget, includeSource, languages, extensions, kinds, path, architectureFacets, testScope, offset, minLines, minComplexity, topN, sort, packAction, format, include, exclude, filePolicies, alreadyPresent, chatFiles, lineNumbers, includeTree, outputPath, artifactPath, startLine, endLine, regex, regexFlags, gitDiffScope, gitLog, statusAudit, timeoutMs, client, repairPlan, persistTelemetry, } = parsedArgs;
|
|
1379
|
+
const { operation, symbol, base, diffScope, from, toRevision, reviewFiles, query, pattern, to, limit, depth, impactMode, direction, relationKinds, minConfidence, includeTests, includeDataFlow, flowVariable, apply, force, detailLevel, prNumber, prState, branches, auditRange, auditBase, auditHead, expectedLogin, worktreeAction, worktreePath, telemetryAction, telemetryRetentionDays, task, changedFiles, repoPath, section, systemAction, repositories, scope, distributed, repositoryIds, components, evidence, relationshipType, requireComplete, repositoryAction, roots, linkedWorktrees, cursor, allowPartial, dryRun, manifestPath, planDigest, identity, file, kind, toIdentity, toFile, toKind, byteBudget, tokenBudget, itemBudget, includeSource, languages, extensions, kinds, path, architectureFacets, testScope, offset, minLines, minComplexity, topN, sort, packAction, format, include, exclude, filePolicies, alreadyPresent, chatFiles, lineNumbers, includeTree, outputPath, artifactPath, startLine, endLine, regex, regexFlags, gitDiffScope, gitLog, statusAudit, timeoutMs, client, repairPlan, persistTelemetry, } = parsedArgs;
|
|
1300
1380
|
const repo = repoPath ?? process.cwd();
|
|
1301
1381
|
const selector = {
|
|
1302
1382
|
identity: expandCompactIdentity(identity),
|
|
@@ -1519,6 +1599,19 @@ async function dispatchKnodinTool(args) {
|
|
|
1519
1599
|
symbol,
|
|
1520
1600
|
repo,
|
|
1521
1601
|
allowPartial,
|
|
1602
|
+
apply,
|
|
1603
|
+
repositories,
|
|
1604
|
+
scope,
|
|
1605
|
+
distributed,
|
|
1606
|
+
repositoryIds,
|
|
1607
|
+
components,
|
|
1608
|
+
relationshipType,
|
|
1609
|
+
from,
|
|
1610
|
+
to,
|
|
1611
|
+
evidence,
|
|
1612
|
+
requireComplete,
|
|
1613
|
+
manifestPath,
|
|
1614
|
+
planDigest,
|
|
1522
1615
|
bounded,
|
|
1523
1616
|
});
|
|
1524
1617
|
}
|
package/docs/CLI.md
CHANGED
|
@@ -35,6 +35,13 @@ knodin repos search --help
|
|
|
35
35
|
knodin update --help
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
+
`repos search` resolves configured system memberships independently for every
|
|
39
|
+
discovered checkout. Symbol search remains primary. When it returns no matches,
|
|
40
|
+
or a multi-term query has only weak single-term symbol coverage, Knodin performs
|
|
41
|
+
a bounded lexical fallback over tracked YAML and shell files. These results are
|
|
42
|
+
labeled `matchType: "tracked-text"` with file and line evidence; they are not
|
|
43
|
+
parsed symbols or a claim of general YAML/shell semantic support.
|
|
44
|
+
|
|
38
45
|
Help uses the active terminal width. Non-TTY output uses a deterministic
|
|
39
46
|
100-column layout so snapshots, documentation, and automation do not depend on
|
|
40
47
|
the caller's environment. Narrow and wide formatting are covered by pure tests;
|
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
# Systems and relationships
|
|
2
2
|
|
|
3
|
+
To have an assistant inspect existing checkouts, propose evidenced membership and relationships, preview exact changes, wait for approval, and validate the result, start from the sanitized [multi-repository system prompt](prompts/declare-multi-repository-system.md).
|
|
4
|
+
|
|
3
5
|
A system is an explicitly configured set of cooperating components. Components
|
|
4
6
|
may represent APIs, resources, repositories, or artifacts. Unrelated
|
|
5
7
|
repositories remain separate even when they share a parent directory or match
|
|
6
8
|
the same search query.
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
Personal system declarations live outside source checkouts at
|
|
11
|
+
`$XDG_CONFIG_HOME/knodin/systems/<system-id>.yaml`; checkout paths remain in:
|
|
10
12
|
|
|
11
13
|
```text
|
|
12
14
|
$XDG_CONFIG_HOME/knodin/repositories.yaml
|
|
13
15
|
```
|
|
14
16
|
|
|
17
|
+
Knodin also reads the legacy nested layout
|
|
18
|
+
`$XDG_CONFIG_HOME/knodin/systems/<name>/knodin.yaml`. From either layout, a
|
|
19
|
+
mapped participating checkout discovers its systems without pointing `--repo`
|
|
20
|
+
at the external configuration directory.
|
|
21
|
+
|
|
22
|
+
Team declarations belong in repository-root `knodin.yaml` and contain stable
|
|
23
|
+
identities without absolute paths. Central configuration writes one selected
|
|
24
|
+
manifest. `--distributed` repeats stable membership/components in each selected
|
|
25
|
+
manifest and keeps an evidenced relationship in its evidence repository.
|
|
26
|
+
|
|
15
27
|
Commands:
|
|
16
28
|
|
|
17
29
|
```bash
|
|
@@ -19,10 +31,18 @@ knodin system list
|
|
|
19
31
|
knodin system show <system-id>
|
|
20
32
|
knodin system validate <system-id>
|
|
21
33
|
knodin system query <system-id>
|
|
34
|
+
knodin system link <system-id> <repo...> --dry-run
|
|
35
|
+
knodin system relate <system-id> --type <type> --from <component> --to <component> \
|
|
36
|
+
--evidence <repo-id>:<path>:<line> --dry-run
|
|
37
|
+
knodin system unlink <system-id> [repo-id...]
|
|
38
|
+
knodin system unrelate <system-id> --type <type> --from <component> --to <component>
|
|
39
|
+
knodin system import <manifest>
|
|
22
40
|
```
|
|
23
41
|
|
|
24
42
|
The existing single MCP gateway exposes the same `system` operation with
|
|
25
|
-
|
|
43
|
+
inspection and lifecycle actions. Link/relate/unlink/unrelate preview by
|
|
44
|
+
default; MCP writes require `apply: true` and return exact planned files and
|
|
45
|
+
semantic changes.
|
|
26
46
|
|
|
27
47
|
Relationship types include dependency, API provider/consumer, deployment,
|
|
28
48
|
provisioning, output/config/path references, events, images, and provenance.
|
|
@@ -40,6 +60,7 @@ source.
|
|
|
40
60
|
discarded. Loaded entries are labeled `legacy-federation` until migrated to
|
|
41
61
|
stable identities.
|
|
42
62
|
|
|
43
|
-
System
|
|
44
|
-
|
|
45
|
-
|
|
63
|
+
System queries return prominently labeled partial results by default and name
|
|
64
|
+
every unavailable repository and omitted relationship. Use
|
|
65
|
+
`--require-complete` when a partial answer must fail. `--allow-partial` remains
|
|
66
|
+
accepted as a compatibility option; absent evidence is never reported as zero.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Declare a knodin multi-repository system
|
|
2
|
+
|
|
3
|
+
Use this command-first prompt after replacing every `<PLACEHOLDER>`; do not include credentials, tokens, private URLs, or source text that is not safe to share with the assistant.
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
Help me declare the knodin system <SYSTEM_ID> from these existing checkouts:
|
|
7
|
+
|
|
8
|
+
- <REPOSITORY_PATH_1>
|
|
9
|
+
- <REPOSITORY_PATH_2>
|
|
10
|
+
|
|
11
|
+
Use <personal|team> scope. For team scope, use <central|distributed> configuration.
|
|
12
|
+
|
|
13
|
+
First run knodin status in each checkout and inspect existing manifests. Propose membership and explicit directional relationships; do not infer membership from sibling paths or repository names and do not invent relationships. Provide an evidence table with repository ID, component IDs/types, relationship type, from, to, repository-relative evidence path, and line.
|
|
14
|
+
|
|
15
|
+
Preview the exact knodin system link and system relate changes. Show every planned file and semantic change, then wait for my approval. After approval, apply the same plan and run system validate and system query. Clearly label unavailable repositories and omitted evidence.
|
|
16
|
+
|
|
17
|
+
For personal scope, record each checkout's branch, tracked files, tracked .gitignore content, and git status before applying; confirm they remain unchanged afterward.
|
|
18
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# knodin 0.8.7
|
|
2
|
+
|
|
3
|
+
This release makes explicit multi-repository systems practical from ordinary
|
|
4
|
+
participating checkouts and ships task-focused assistant workflows.
|
|
5
|
+
|
|
6
|
+
- `knodin system link`, `relate`, `unlink`, `unrelate`, and `import` replace
|
|
7
|
+
manual multi-repository YAML plumbing for personal, central-team, and
|
|
8
|
+
distributed-team systems. Mutations preview exact files and semantic changes;
|
|
9
|
+
MCP writes are bound to the approved preview.
|
|
10
|
+
- Personal systems auto-discover from mapped checkouts, including legacy nested
|
|
11
|
+
manifests. System queries label unavailable repositories and omitted evidence,
|
|
12
|
+
while `--require-complete` preserves fail-closed workflows.
|
|
13
|
+
- Portfolio search resolves system memberships per checkout and uses a bounded,
|
|
14
|
+
explicitly labeled committed-text fallback for weak YAML/shell workflow
|
|
15
|
+
queries. It does not claim general YAML or shell semantic parsing.
|
|
16
|
+
- Seven packaged `knodin-*` skills cover exploration, debugging, impact,
|
|
17
|
+
refactoring, review, systems, and lifecycle work for Codex, Claude, and Gemini.
|
|
18
|
+
Managed installation preserves user-authored and modified skills.
|
|
19
|
+
- Personal initialization remains byte-clean in source checkouts, including
|
|
20
|
+
tracked `.gitignore` content and branch/worktree state.
|
|
21
|
+
- Release builds now mark `dist/bin/launcher.js` executable before packing. This
|
|
22
|
+
fixes Homebrew installations where `knodin` was linked correctly but shells
|
|
23
|
+
ignored the non-executable launcher or returned `permission denied`.
|
|
24
|
+
|
|
25
|
+
Knodin still treats ordinary YAML and shell files as lexical fallback evidence,
|
|
26
|
+
not native graph inputs. Partial system results remain useful only within their
|
|
27
|
+
reported unavailable repositories and omitted relationships.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knodin",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
4
4
|
"description": "knodin — source-evidenced local code intelligence with known bounds. Stable identity, fresh evidence, truthful budgets, and recoverable bounded views.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
},
|
|
22
22
|
"files": [
|
|
23
23
|
"dist",
|
|
24
|
+
"skills",
|
|
25
|
+
"docs/prompts/declare-multi-repository-system.md",
|
|
24
26
|
"docs/DEAD-CODE-AND-IMPACT.md",
|
|
25
27
|
"docs/DOCTOR-AND-UPDATES.md",
|
|
26
28
|
"docs/DIAGNOSTICS.md",
|
|
@@ -63,6 +65,7 @@
|
|
|
63
65
|
"docs/releases/0.8.4.md",
|
|
64
66
|
"docs/releases/0.8.5.md",
|
|
65
67
|
"docs/releases/0.8.6.md",
|
|
68
|
+
"docs/releases/0.8.7.md",
|
|
66
69
|
"docs/assets/knodin-favicon.svg",
|
|
67
70
|
"docs/SYSTEMS-AND-RELATIONSHIPS.md",
|
|
68
71
|
"docs/TELEMETRY.md",
|
|
@@ -87,7 +90,7 @@
|
|
|
87
90
|
"start": "tsx src/server.ts",
|
|
88
91
|
"cli": "tsx bin/cli.ts",
|
|
89
92
|
"clean": "node scripts/clean-dist.mjs",
|
|
90
|
-
"build": "npm run clean && tsc -p tsconfig.build.json",
|
|
93
|
+
"build": "npm run clean && tsc -p tsconfig.build.json && node scripts/finalize-build.mjs",
|
|
91
94
|
"typecheck": "tsc --noEmit",
|
|
92
95
|
"test": "tsx scripts/run-vitest-shards.ts",
|
|
93
96
|
"test:handles": "vitest run --reporter=verbose --reporter=hanging-process",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: knodin-debug
|
|
3
|
+
description: Debug a local software failure by tracing source-evidenced flows, callers, dependencies, and recent changes with knodin. Use for reproducible defects, exceptions, failing tests, regressions, or root-cause investigation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Debug with knodin
|
|
7
|
+
|
|
8
|
+
1. Establish the failure and call MCP `context` with the symptom; fall back to `knodin context` if MCP is unavailable.
|
|
9
|
+
2. Use `explain`, `query` with callers/callees/data-flow patterns, and bounded source to test one cause at a time.
|
|
10
|
+
3. Use `review` against the relevant base when a regression is plausible.
|
|
11
|
+
4. Separate observed evidence from hypotheses; name stale, missing, or ambiguous graph coverage.
|
|
12
|
+
5. Load `knodin docs diagnostics` or command help only for parameters not already known.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: knodin-explore
|
|
3
|
+
description: Explore an unfamiliar local codebase with source-evidenced architecture, symbols, flows, and bounded context. Use for codebase orientation, locating implementations, understanding architecture, or answering “where/how does this work?” questions.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Explore with knodin
|
|
7
|
+
|
|
8
|
+
1. Call the connected knodin MCP `context` operation with the task before broad traversal. If MCP is unavailable, run `knodin context <task>`.
|
|
9
|
+
2. Use MCP `search`, `map`, or `explain` for the smallest source-evidenced answer. Fall back to the matching CLI commands.
|
|
10
|
+
3. Report file paths, symbol identities, evidence, freshness, and known bounds. Treat ambiguity or stale evidence explicitly.
|
|
11
|
+
4. Load `knodin docs query-patterns` or command help only when detailed parameters are needed.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: knodin-impact
|
|
3
|
+
description: Assess upstream and downstream change impact with source-evidenced dependencies and known bounds. Use before meaningful edits, API changes, deletions, migrations, or when asked what could break.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Assess impact with knodin
|
|
7
|
+
|
|
8
|
+
1. Resolve the symbol unambiguously with MCP `explain` or `search`.
|
|
9
|
+
2. Call MCP `query` with the `impact` pattern and explicit direction; fall back to `knodin query impact <symbol> --direction upstream|downstream|both`.
|
|
10
|
+
3. Report direct and transitive consumers, tests, cross-repository evidence, freshness, and omissions.
|
|
11
|
+
4. Never turn heuristic or partial evidence into a safe-deletion claim. Load `knodin docs dead-code` only when deletion policy details are needed.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: knodin-lifecycle
|
|
3
|
+
description: Inspect and repair knodin graph freshness, lifecycle hooks, agent integration, installation, and packaged skills. Use for init, status, repair, doctor, stale graphs, broken hooks, configuration, or assistant-skill installation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Maintain knodin
|
|
7
|
+
|
|
8
|
+
1. Run MCP status; fall back to `knodin status`. Do not rely on graph evidence when repair is required.
|
|
9
|
+
2. Follow reported repair steps: use `knodin repair` for graph damage and `knodin init` for displaced lifecycle hooks.
|
|
10
|
+
3. Use `knodin skills doctor` for managed-skill health and `knodin skills install|remove` for explicit lifecycle changes.
|
|
11
|
+
4. Preserve scope: personal locations remain outside repositories; team locations are commit-ready; CLI-only installs no skills.
|
|
12
|
+
5. Report freshness, hook state, supported clients, managed/unmanaged collisions, and remaining limitations. Load `knodin docs doctor` only for detailed procedures.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: knodin-refactor
|
|
3
|
+
description: Plan and verify source-evidenced local refactors and renames with ambiguity-safe symbol identity and impact checks. Use for renaming, moving, extracting, deleting, or restructuring code.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Refactor with knodin
|
|
7
|
+
|
|
8
|
+
1. Resolve the exact symbol using MCP `explain`; fall back to `knodin explain` and stop on ambiguity.
|
|
9
|
+
2. Run MCP `query` with `impact` upstream before editing and summarize material risk.
|
|
10
|
+
3. Prefer knodin’s rename operation for supported renames; preview before apply. Otherwise edit only source-confirmed references.
|
|
11
|
+
4. Reindex changed files when immediate freshness is required, then rerun impact and relevant tests.
|
|
12
|
+
5. Load `knodin docs rename-safety` or command help only for detailed parameters.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: knodin-review
|
|
3
|
+
description: Review a local change or branch using source-evidenced risk, dependency, history, and bounded context. Use for code review, pre-PR review, regression risk, or checking whether a diff missed consumers.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Review with knodin
|
|
7
|
+
|
|
8
|
+
1. Call MCP `review` with an explicit diff scope and base; fall back to `knodin review --scope compare <base>`.
|
|
9
|
+
2. Inspect high-risk changed symbols with `explain` and upstream `impact` queries.
|
|
10
|
+
3. Verify findings in source and report severity, evidence paths, affected consumers, and coverage bounds.
|
|
11
|
+
4. Do not equate a zero-match or partial result with safety. Load `knodin docs git-history` only when deeper history parameters are needed.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: knodin-systems
|
|
3
|
+
description: Discover, declare, validate, and query explicit multi-repository knodin systems and evidenced relationships. Use for linking repositories, cross-repository architecture, partial checkouts, system manifests, or relationship maintenance.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Manage systems with knodin
|
|
7
|
+
|
|
8
|
+
1. Inspect candidate repositories; never infer membership from sibling paths or names.
|
|
9
|
+
2. Propose repository/component IDs and explicit directional relationships in an evidence table with repository-relative path and line.
|
|
10
|
+
3. Preview with MCP `system` actions (omit `apply` or set it false); fall back to CLI `system link|relate --dry-run`. Show exact files and semantic changes.
|
|
11
|
+
4. Wait for approval before applying. For MCP writes set `apply: true`; for CLI rerun without `--dry-run`.
|
|
12
|
+
5. Validate the system and label unavailable members and omitted evidence. Use `--require-complete` only when completeness is mandatory.
|
|
13
|
+
6. For personal scope, confirm branches, tracked files, and working-tree state in every checkout remain unchanged.
|
|
14
|
+
7. Load `knodin docs systems` or command help only when detailed options are needed.
|