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.
@@ -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 an explicit revision pair; requires `to`.",
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: ["list", "show", "validate", "query"],
498
- description: "system only: list configured systems, show or validate one system, or query its declared relationships.",
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, configRoot) {
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(configRoot), target),
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(systemConfig, target),
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(systemConfig, target),
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(systemConfig, target),
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, discoveryRoots[0] ?? repo);
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, allowPartial, bounded } = options;
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, allowPartial === true, validation), "system:query");
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
- Team configuration belongs in repository-root `knodin.yaml` and contains stable
9
- identities without local absolute paths. Personal checkout paths belong in:
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
- `systemAction=list|show|validate|query`.
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 validation fails closed for unresolved repository identities or missing
44
- required checkouts. Partial query behavior must be explicit and name every
45
- omitted component; absent evidence is never reported as zero.
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.6",
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,4 @@
1
+ interface:
2
+ display_name: "Knodin Debug"
3
+ short_description: "Use knodin for debug workflows"
4
+ default_prompt: "Use $knodin-debug to help with this codebase task."
@@ -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,4 @@
1
+ interface:
2
+ display_name: "Knodin Explore"
3
+ short_description: "Use knodin for explore workflows"
4
+ default_prompt: "Use $knodin-explore to help with this codebase task."
@@ -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,4 @@
1
+ interface:
2
+ display_name: "Knodin Impact"
3
+ short_description: "Use knodin for impact workflows"
4
+ default_prompt: "Use $knodin-impact to help with this codebase task."
@@ -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,4 @@
1
+ interface:
2
+ display_name: "Knodin Lifecycle"
3
+ short_description: "Use knodin for lifecycle workflows"
4
+ default_prompt: "Use $knodin-lifecycle to help with this codebase task."
@@ -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,4 @@
1
+ interface:
2
+ display_name: "Knodin Refactor"
3
+ short_description: "Use knodin for refactor workflows"
4
+ default_prompt: "Use $knodin-refactor to help with this codebase task."
@@ -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,4 @@
1
+ interface:
2
+ display_name: "Knodin Review"
3
+ short_description: "Use knodin for review workflows"
4
+ default_prompt: "Use $knodin-review to help with this codebase task."
@@ -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.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Knodin Systems"
3
+ short_description: "Use knodin for systems workflows"
4
+ default_prompt: "Use $knodin-systems to help with this codebase task."