@qiqiangvae/dsh-obsidian 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/ATTRIBUTION.md +36 -0
  2. package/LICENSE +21 -0
  3. package/README.md +102 -0
  4. package/cordis.patch.yml +23 -0
  5. package/index.js +5 -0
  6. package/lib/index.d.ts +64 -0
  7. package/lib/index.d.ts.map +1 -0
  8. package/lib/index.js +351 -0
  9. package/lib/index.js.map +1 -0
  10. package/lib/lint.d.ts +25 -0
  11. package/lib/lint.d.ts.map +1 -0
  12. package/lib/lint.js +145 -0
  13. package/lib/lint.js.map +1 -0
  14. package/lib/scaffold.d.ts +26 -0
  15. package/lib/scaffold.d.ts.map +1 -0
  16. package/lib/scaffold.js +67 -0
  17. package/lib/scaffold.js.map +1 -0
  18. package/lib/search.d.ts +41 -0
  19. package/lib/search.d.ts.map +1 -0
  20. package/lib/search.js +127 -0
  21. package/lib/search.js.map +1 -0
  22. package/lib/skills.d.ts +18 -0
  23. package/lib/skills.d.ts.map +1 -0
  24. package/lib/skills.js +83 -0
  25. package/lib/skills.js.map +1 -0
  26. package/lib/types.d.ts +55 -0
  27. package/lib/types.d.ts.map +1 -0
  28. package/lib/types.js +6 -0
  29. package/lib/types.js.map +1 -0
  30. package/lib/vault.d.ts +69 -0
  31. package/lib/vault.d.ts.map +1 -0
  32. package/lib/vault.js +315 -0
  33. package/lib/vault.js.map +1 -0
  34. package/package.json +66 -0
  35. package/skills/defuddle/SKILL.md +35 -0
  36. package/skills/json-canvas/SKILL.md +61 -0
  37. package/skills/obsidian-bases/SKILL.md +51 -0
  38. package/skills/obsidian-cli/SKILL.md +41 -0
  39. package/skills/obsidian-markdown/SKILL.md +59 -0
  40. package/skills/save/SKILL.md +33 -0
  41. package/skills/think/SKILL.md +27 -0
  42. package/skills/wiki/SKILL.md +45 -0
  43. package/skills/wiki-ingest/SKILL.md +40 -0
  44. package/skills/wiki-lint/SKILL.md +36 -0
  45. package/skills/wiki-query/SKILL.md +34 -0
package/ATTRIBUTION.md ADDED
@@ -0,0 +1,36 @@
1
+ # Attribution
2
+
3
+ `dsh-obsidian` is a merged adaptation of the following MIT-licensed works:
4
+
5
+ ## Code adapted (with modification)
6
+
7
+ - **[Lion-1209/dsh-plugin-wiki-skills](https://github.com/Lion-1209/dsh-plugin-wiki-skills)** (MIT, © 2026 Lion-1209)
8
+ - Skills content adapted: `wiki`, `wiki-ingest`, `wiki-query`, `wiki-lint`, `save`, `think`
9
+ - Reference skills ported in: `obsidian-markdown`, `obsidian-bases`, `defuddle` (originally from kepano/obsidian-skills)
10
+
11
+ - **[Lion-1209/dsh-plugin-wiki-tools](https://github.com/Lion-1209/dsh-plugin-wiki-tools)** (MIT, © 2026 Lion-1209)
12
+ - Vault operation contracts (LLM Wiki pattern) followed
13
+ - **Re-implemented from scratch in TypeScript** for the new DSH cordis API (`ctx.tools.register`)
14
+ - BM25 search, type-routing, frontmatter completion, index/log bookkeeping, health check
15
+
16
+ ## Reference (parity target, not directly forked)
17
+
18
+ - **[AgriciDaniel/claude-obsidian](https://github.com/AgriciDaniel/claude-obsidian)** (MIT, © 2026 AgriciDaniel)
19
+ - Long-term parity target. The `PORTING_PLAN.md` lists which v2.x features we will incrementally port.
20
+ - **No code copied** from this project.
21
+
22
+ - **[kepano/obsidian-skills](https://github.com/kepano/obsidian-skills)** (MIT)
23
+ - Reference for Obsidian Flavored Markdown syntax in skills.
24
+
25
+ ## Changes from upstream
26
+
27
+ 1. **Merged two plugins** (`dsh-plugin-wiki-skills` + `dsh-plugin-wiki-tools`) into a single `dsh-obsidian` plugin.
28
+ 2. **Re-implemented tools layer** in modern TypeScript using the new cordis `apply(ctx)` + `ctx.tools.register` API (the old `ctx.defineTool` form was deprecated).
29
+ 3. **Added kepano's `obsidian-cli` and `json-canvas` skills** that the Lion-1209 fork omitted.
30
+ 4. **Removed the DSH plugin auto-update dependency** — `dsh-obsidian` is self-contained, versioned with this repo, and can be installed from this Git URL.
31
+ 5. **Roadmap to v2.x parity** tracked in [`PORTING_PLAN.md`](./PORTING_PLAN.md).
32
+
33
+ ## License
34
+
35
+ - This package: MIT (see [`LICENSE`](./LICENSE))
36
+ - All upstream works: MIT (see [`ORIGINAL_LICENSE`](./ORIGINAL_LICENSE))
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 qiqiangvae
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # dsh-obsidian
2
+
3
+ Self-organizing AI second brain for Obsidian, as a single [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin.
4
+
5
+ Targets parity with [AgriciDaniel/claude-obsidian](https://github.com/AgriciDaniel/claude-obsidian) (MIT).
6
+ Built on the LLM Wiki pattern (Andrej Karpathy).
7
+ Merged fork of `dsh-plugin-wiki-skills` + `dsh-plugin-wiki-tools` — see [`ATTRIBUTION.md`](./ATTRIBUTION.md).
8
+
9
+ ## Why this exists
10
+
11
+ The two upstream DSH plugins were great but:
12
+
13
+ 1. **DSH is in active development and breaks the public cordis API often.**
14
+ When that happens, the two plugins stop loading. The original maintainer
15
+ updates at a slower cadence than the framework.
16
+ 2. **Splitting skills and tools is good architecture but bad UX for one person.**
17
+ You almost always want both.
18
+
19
+ So: one plugin, versioned together, with a clear upgrade path to v2.x features
20
+ (see [`PORTING_PLAN.md`](./PORTING_PLAN.md)).
21
+
22
+ ## Install
23
+
24
+ Prerequisites:
25
+
26
+ - DSH 0.x or newer (with `dsh plugin` CLI), Node ≥ 22.19
27
+ - An Obsidian vault somewhere on disk
28
+
29
+ ```bash
30
+ # 1. Add the plugin
31
+ dsh plugin --profile web add github:qiqiangvae/dsh-obsidian
32
+
33
+ # 2. Set your vault path in your profile's cordis.patch.yml
34
+ # (~/.dsh/profiles/web/cordis.patch.yml)
35
+ #
36
+ # - id: dsh-obsidian
37
+ # config:
38
+ # vaultPath: /absolute/path/to/your/obsidian/vault
39
+ # # optional:
40
+ # # typeFolders: { domain: "wiki/areas" }
41
+ # # maxQueryResults: 10
42
+ #
43
+ # 3. Restart DSH
44
+ dsh web
45
+
46
+ # 4. (optional) Scaffold a fresh vault
47
+ # In DSH: run the wiki_scaffold tool with { template: "default", apply: true }
48
+ ```
49
+
50
+ To install from a local checkout (e.g. while developing this plugin):
51
+
52
+ ```bash
53
+ git clone git@github.com:qiqiangvae/dsh-obsidian.git
54
+ cd dsh-obsidian
55
+ pnpm install # for dev dependencies (typescript, @types)
56
+ pnpm run build # compiles src/ → lib/
57
+ dsh plugin --profile web add link:$(pwd)
58
+ ```
59
+
60
+ ## What you get
61
+
62
+ ### Tools (registered on `ctx.tools`)
63
+
64
+ | Tool | What it does |
65
+ | ---- | ------------ |
66
+ | `wiki_query` | BM25 search with snippet + link graph; quick mode returns hot + index verbatim |
67
+ | `wiki_write` | One-page write with type-routing, frontmatter completion, index/log bookkeeping, source-hash delta skip |
68
+ | `wiki_lint` | Health check: duplicates, dead links, orphans, frontmatter gaps, empty sections, stale index/hot |
69
+ | `wiki_scaffold` | Initialize the LLM Wiki layout (dry-run by default) |
70
+ | `wiki_rename` | Rename a page with machinery protection |
71
+ | `wiki_list` | List all page titles |
72
+
73
+ ### Skills (registered on `ctx.skills`)
74
+
75
+ From the Lion-1209 v1 suite:
76
+
77
+ - `wiki` — vault scaffolding and routing
78
+ - `wiki-ingest` — capture sources into the vault
79
+ - `wiki-query` — answer from the vault with citations
80
+ - `wiki-lint` — health-check workflow
81
+ - `save` — file conversation insights
82
+ - `think` — 10-principle reasoning loop
83
+
84
+ Plus reference skills from kepano (Obsidian Flavored Markdown, Bases) and
85
+ DSH-flavoured extensions:
86
+
87
+ - `obsidian-markdown`, `obsidian-bases`, `json-canvas`, `defuddle`, `obsidian-cli`
88
+
89
+ ## Develop
90
+
91
+ ```bash
92
+ pnpm install
93
+ pnpm run build # tsc → lib/
94
+ pnpm test # node --test test/
95
+ ```
96
+
97
+ Edit code under `src/`, build to `lib/`, restart DSH. To hot-reload during
98
+ development, also run `pnpm run dev:web` from the DSH checkout.
99
+
100
+ ## License
101
+
102
+ MIT. See [`LICENSE`](./LICENSE) and [`ATTRIBUTION.md`](./ATTRIBUTION.md).
@@ -0,0 +1,23 @@
1
+ # cordis.patch.yml — DeepSeek Harness bundle patch for dsh-obsidian.
2
+ #
3
+ # When this package is installed as a bundle (the dsh.bundle.patch field in
4
+ # package.json points to this file), DSH applies this patch to the profile
5
+ # root. The `- insert:` form adds a single loader row under the id
6
+ # `dsh-obsidian`. The row's `name` is the npm package name, which DSH uses
7
+ # to resolve the entry module (this package's `main`, i.e. `./index.js`).
8
+ #
9
+ # vaultPath is REQUIRED: override this row from your profile's own
10
+ # cordis.patch.yml, e.g.
11
+ #
12
+ # - id: dsh-obsidian
13
+ # config:
14
+ # vaultPath: /absolute/path/to/your/obsidian/vault
15
+ # typeFolders: { domain: "wiki/areas" }
16
+ # maxQueryResults: 10
17
+ #
18
+ # If vaultPath is empty at boot, the plugin fails loud with clear
19
+ # instructions — never silently writes to the wrong directory.
20
+
21
+ - insert:
22
+ - id: dsh-obsidian
23
+ name: "@qiqiangvae/dsh-obsidian"
package/index.js ADDED
@@ -0,0 +1,5 @@
1
+ // index.js — DSH entry point. Re-exports the compiled apply() from lib/.
2
+ // Keeping this file in the repo root so DSH's `main` field resolves to a
3
+ // conventional location; the real implementation lives in lib/index.js.
4
+
5
+ export { name, inject, apply, default } from './lib/index.js';
package/lib/index.d.ts ADDED
@@ -0,0 +1,64 @@
1
+ /**
2
+ * index.ts — DSH plugin entry point for dsh-obsidian.
3
+ *
4
+ * Re-implementation of dsh-plugin-wiki-tools + dsh-plugin-wiki-skills, using
5
+ * the modern `apply(ctx, config)` signature and the `defineTool()` helper
6
+ * from @deepseek-ai/dsh-tools. Each tool returns structured data; the render
7
+ * function shapes the model-facing text.
8
+ *
9
+ * Required config (in your profile's cordis.patch.yml):
10
+ *
11
+ * - id: dsh-obsidian
12
+ * config:
13
+ * vaultPath: /absolute/path/to/your/obsidian/vault
14
+ *
15
+ * The boot fails loud if vaultPath is missing.
16
+ */
17
+ import z from '@deepseek-ai/schemastery';
18
+ import type { Context } from './types.js';
19
+ export declare const Config: z<Schemastery.ObjectS<{
20
+ /** Absolute path to the Obsidian vault root. */
21
+ vaultPath: z<string, string>;
22
+ /** Max wiki_query hits in standard mode. */
23
+ maxQueryResults: z<number, number>;
24
+ /** Optional per-type folder overrides. */
25
+ typeFolders: z<Schemastery.ObjectS<{}>, Schemastery.ObjectT<{}>>;
26
+ }>, Schemastery.ObjectT<{
27
+ /** Absolute path to the Obsidian vault root. */
28
+ vaultPath: z<string, string>;
29
+ /** Max wiki_query hits in standard mode. */
30
+ maxQueryResults: z<number, number>;
31
+ /** Optional per-type folder overrides. */
32
+ typeFolders: z<Schemastery.ObjectS<{}>, Schemastery.ObjectT<{}>>;
33
+ }>>;
34
+ /** Hand-written mirror of the schema above; dsh passes this exact shape to apply. */
35
+ export interface ObsidianConfig {
36
+ vaultPath: string;
37
+ maxQueryResults: number;
38
+ typeFolders: Record<string, string>;
39
+ }
40
+ export declare const name = "dsh-obsidian";
41
+ export declare const inject: string[];
42
+ export declare function apply(ctx: Context, config: ObsidianConfig): Promise<void>;
43
+ declare const _default: {
44
+ name: string;
45
+ inject: string[];
46
+ Config: z<Schemastery.ObjectS<{
47
+ /** Absolute path to the Obsidian vault root. */
48
+ vaultPath: z<string, string>;
49
+ /** Max wiki_query hits in standard mode. */
50
+ maxQueryResults: z<number, number>;
51
+ /** Optional per-type folder overrides. */
52
+ typeFolders: z<Schemastery.ObjectS<{}>, Schemastery.ObjectT<{}>>;
53
+ }>, Schemastery.ObjectT<{
54
+ /** Absolute path to the Obsidian vault root. */
55
+ vaultPath: z<string, string>;
56
+ /** Max wiki_query hits in standard mode. */
57
+ maxQueryResults: z<number, number>;
58
+ /** Optional per-type folder overrides. */
59
+ typeFolders: z<Schemastery.ObjectS<{}>, Schemastery.ObjectT<{}>>;
60
+ }>>;
61
+ apply: typeof apply;
62
+ };
63
+ export default _default;
64
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,CAAC,MAAM,0BAA0B,CAAC;AAQzC,OAAO,KAAK,EAAgB,OAAO,EAAkB,MAAM,YAAY,CAAC;AAQxE,eAAO,MAAM,MAAM;IACjB,gDAAgD;;IAEhD,4CAA4C;;IAE5C,0CAA0C;;;IAJ1C,gDAAgD;;IAEhD,4CAA4C;;IAE5C,0CAA0C;;GAE1C,CAAC;AAEH,qFAAqF;AACrF,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAMD,eAAO,MAAM,IAAI,iBAAiB,CAAC;AAInC,eAAO,MAAM,MAAM,UAAsB,CAAC;AAiB1C,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA6N/E;;;;;QArQC,gDAAgD;;QAEhD,4CAA4C;;QAE5C,0CAA0C;;;QAJ1C,gDAAgD;;QAEhD,4CAA4C;;QAE5C,0CAA0C;;;;;AA0W5C,wBAA+C"}
package/lib/index.js ADDED
@@ -0,0 +1,351 @@
1
+ /**
2
+ * index.ts — DSH plugin entry point for dsh-obsidian.
3
+ *
4
+ * Re-implementation of dsh-plugin-wiki-tools + dsh-plugin-wiki-skills, using
5
+ * the modern `apply(ctx, config)` signature and the `defineTool()` helper
6
+ * from @deepseek-ai/dsh-tools. Each tool returns structured data; the render
7
+ * function shapes the model-facing text.
8
+ *
9
+ * Required config (in your profile's cordis.patch.yml):
10
+ *
11
+ * - id: dsh-obsidian
12
+ * config:
13
+ * vaultPath: /absolute/path/to/your/obsidian/vault
14
+ *
15
+ * The boot fails loud if vaultPath is missing.
16
+ */
17
+ import { dirname, join } from 'node:path';
18
+ import { fileURLToPath } from 'node:url';
19
+ import { existsSync } from 'node:fs';
20
+ import { defineTool } from '@deepseek-ai/dsh-tools';
21
+ import z from '@deepseek-ai/schemastery';
22
+ import { resolveLayout } from './vault.js';
23
+ import { search } from './search.js';
24
+ import { writePage, renamePage, listAllTitles } from './vault.js';
25
+ import { lint, writeLintReport } from './lint.js';
26
+ import { scaffold } from './scaffold.js';
27
+ import { registerAllSkills } from './skills.js';
28
+ const __dirname = dirname(fileURLToPath(import.meta.url));
29
+ // ──────────────────────────────────────────────────────────────────────────────
30
+ // Config schema (validated by Schemastery at load time)
31
+ // ──────────────────────────────────────────────────────────────────────────────
32
+ export const Config = z.object({
33
+ /** Absolute path to the Obsidian vault root. */
34
+ vaultPath: z.string().required(),
35
+ /** Max wiki_query hits in standard mode. */
36
+ maxQueryResults: z.number().default(10),
37
+ /** Optional per-type folder overrides. */
38
+ typeFolders: z.object({}),
39
+ });
40
+ // ──────────────────────────────────────────────────────────────────────────────
41
+ // Plugin identity
42
+ // ──────────────────────────────────────────────────────────────────────────────
43
+ export const name = 'dsh-obsidian';
44
+ // Inject: `tools` (the dsh-tools service that owns our wiki_query etc.) and
45
+ // `skills` (the dsh-skills service that bundles the SKILL.md catalog).
46
+ // The loader waits for these to be available before calling apply().
47
+ export const inject = ['tools', 'skills'];
48
+ // ──────────────────────────────────────────────────────────────────────────────
49
+ // register helper — our local ToolDefinition is intentionally loose (the
50
+ // dsh-tools types require `execute` to return a strictly-typed `JsonValue`).
51
+ // At runtime, our plain objects are JSON-serializable; the cast is safe.
52
+ // We pass through defineTool() so dsh-tools still validates the args schema
53
+ // and the output schema on every call.
54
+ // ──────────────────────────────────────────────────────────────────────────────
55
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
56
+ const reg = (ctx, def) => ctx.tools.register(defineTool(def));
57
+ // ──────────────────────────────────────────────────────────────────────────────
58
+ // Apply — runs once at boot, after deps are ready
59
+ // ──────────────────────────────────────────────────────────────────────────────
60
+ export async function apply(ctx, config) {
61
+ ctx.logger.info('dsh-obsidian activating…');
62
+ if (typeof config.vaultPath !== 'string' || config.vaultPath.length === 0) {
63
+ throw new Error('dsh-obsidian: config vaultPath is required. Set it on the dsh-obsidian row ' +
64
+ 'in your profile cordis.patch.yml, e.g.\n' +
65
+ ' - id: dsh-obsidian\n' +
66
+ ' config:\n' +
67
+ ' vaultPath: /absolute/path/to/your/obsidian/vault');
68
+ }
69
+ if (!existsSync(config.vaultPath)) {
70
+ ctx.logger.warn(`dsh-obsidian: vaultPath does not exist: ${config.vaultPath} ` +
71
+ `(create it or run wiki_scaffold to initialize)`);
72
+ }
73
+ // Materialize a PluginConfig for the helpers
74
+ const pluginConfig = {
75
+ vaultPath: config.vaultPath,
76
+ typeFolders: (config.typeFolders ?? {}),
77
+ maxQueryResults: config.maxQueryResults ?? 10,
78
+ };
79
+ const layout = resolveLayout(config.vaultPath, pluginConfig);
80
+ // ── tools ────────────────────────────────────────────────────────────────
81
+ // wiki_query
82
+ reg(ctx, {
83
+ name: 'wiki_query',
84
+ description: 'Search the knowledge vault. Quick mode returns the hot cache and master ' +
85
+ 'index verbatim (read those before any page). Standard mode runs BM25 full-text ' +
86
+ 'search over every wiki page and returns ranked matches with snippets, inbound ' +
87
+ 'links, and outbound link counts.',
88
+ parameters: {
89
+ query: { type: 'string', required: true, description: 'search text or topic' },
90
+ limit: { type: 'number', description: 'max hits (default from config)' },
91
+ mode: {
92
+ type: 'string',
93
+ enum: ['quick', 'standard'],
94
+ description: 'quick returns hot.md + index.md only; standard searches all pages',
95
+ },
96
+ },
97
+ output: {
98
+ schema: { type: 'object', additionalProperties: true },
99
+ render: (_args, value) => [
100
+ { type: 'text', text: renderQuery(value) },
101
+ ],
102
+ },
103
+ execute: async (args) => {
104
+ const limit = args.limit ?? pluginConfig.maxQueryResults ?? 10;
105
+ const mode = args.mode ?? 'standard';
106
+ return search(layout.wikiDir, { query: args.query, limit, mode });
107
+ },
108
+ presentCall: (args) => ({
109
+ card: 'generic',
110
+ title: `Query wiki: ${args.query}`,
111
+ kind: 'read',
112
+ rawInput: args.query,
113
+ }),
114
+ });
115
+ // wiki_write
116
+ reg(ctx, {
117
+ name: 'wiki_write',
118
+ description: 'Write or update one wiki page with full bookkeeping: type-routed folder, ' +
119
+ 'frontmatter completion (keeps `created` and unknown fields), filename-uniqueness ' +
120
+ 'guard, master-index entry, and log entry. With source_path, records the source ' +
121
+ 'SHA-256 and skips unchanged content unless `force`. Returns unresolvedLinks so ' +
122
+ 'forward links during multi-page ingests are surfaced for the next pass.',
123
+ parameters: {
124
+ title: { type: 'string', required: true, description: 'page title; also filename' },
125
+ type: {
126
+ type: 'string',
127
+ required: true,
128
+ enum: ['domain', 'area', 'project', 'resource', 'source', 'archive'],
129
+ description: 'page type, drives folder routing',
130
+ },
131
+ content: { type: 'string', required: true, description: 'markdown body (no frontmatter; it is added)' },
132
+ tags: { type: 'array', items: { type: 'string' }, description: 'optional frontmatter tags' },
133
+ source_path: { type: 'string', description: 'optional path to source file; hash recorded for delta' },
134
+ force: { type: 'boolean', description: 'overwrite even when source hash unchanged' },
135
+ },
136
+ output: {
137
+ schema: { type: 'object', additionalProperties: true },
138
+ render: (args, value) => [
139
+ { type: 'text', text: renderWrite(args, value) },
140
+ ],
141
+ },
142
+ execute: async (args) => {
143
+ return writePage(config.vaultPath, pluginConfig, {
144
+ title: args.title,
145
+ type: args.type,
146
+ content: args.content,
147
+ tags: args.tags,
148
+ source_path: args.source_path,
149
+ force: args.force,
150
+ });
151
+ },
152
+ presentCall: (args) => ({
153
+ card: 'generic',
154
+ title: `Write wiki page: ${args.title}`,
155
+ kind: 'other',
156
+ rawInput: { title: args.title, type: args.type },
157
+ }),
158
+ });
159
+ // wiki_rename
160
+ reg(ctx, {
161
+ name: 'wiki_rename',
162
+ description: 'Rename a wiki page. Refuses machinery pages (Lint Report, index, hot, log) ' +
163
+ 'and rejects non-portable filenames.',
164
+ parameters: {
165
+ old_title: { type: 'string', required: true },
166
+ new_title: { type: 'string', required: true },
167
+ },
168
+ output: {
169
+ schema: { type: 'object', additionalProperties: true },
170
+ render: (_args, value) => [{ type: 'text', text: renderRename(value) }],
171
+ },
172
+ execute: async (args) => {
173
+ return renamePage(config.vaultPath, pluginConfig, args.old_title, args.new_title);
174
+ },
175
+ presentCall: (args) => ({
176
+ card: 'generic',
177
+ title: `Rename wiki page: ${args.old_title} → ${args.new_title}`,
178
+ kind: 'other',
179
+ rawInput: { from: args.old_title, to: args.new_title },
180
+ }),
181
+ });
182
+ // wiki_lint
183
+ reg(ctx, {
184
+ name: 'wiki_lint',
185
+ description: 'Health-check the knowledge vault: duplicate filenames, dead wikilinks, orphan ' +
186
+ 'pages, frontmatter gaps, empty sections, stale index entries, stale hot cache. ' +
187
+ 'Report only — every issue carries a suggestion. Writes the dated report to ' +
188
+ 'wiki/meta/Lint Report <date>.md.',
189
+ parameters: {
190
+ fix: { type: 'boolean', description: 'placeholder for future parity; report-only in v0.1' },
191
+ },
192
+ output: {
193
+ schema: { type: 'object', additionalProperties: true },
194
+ render: (_args, value) => [{ type: 'text', text: renderLint(value) }],
195
+ },
196
+ execute: async (args) => {
197
+ const report = lint(config.vaultPath, pluginConfig, { fix: args.fix });
198
+ const reportPath = writeLintReport(config.vaultPath, pluginConfig, report);
199
+ return { ...report, reportPath };
200
+ },
201
+ presentCall: () => ({ card: 'generic', title: 'Lint wiki vault', kind: 'other' }),
202
+ });
203
+ // wiki_scaffold
204
+ reg(ctx, {
205
+ name: 'wiki_scaffold',
206
+ description: 'Scaffold a wiki vault: wiki/, .raw/, wiki/meta/, and seed files (index.md, ' +
207
+ 'hot.md, log.md, Inbox.md). Dry-run by default — pass `apply: true` to write.',
208
+ parameters: {
209
+ template: {
210
+ type: 'string',
211
+ enum: ['default', 'minimal', 'research'],
212
+ description: 'scaffold template',
213
+ },
214
+ apply: { type: 'boolean', description: 'actually write files (default false = dry run)' },
215
+ },
216
+ output: {
217
+ schema: { type: 'object', additionalProperties: true },
218
+ render: (_args, value) => [{ type: 'text', text: renderScaffold(value) }],
219
+ },
220
+ execute: async (args) => {
221
+ return scaffold(config.vaultPath, pluginConfig, {
222
+ template: args.template,
223
+ apply: args.apply,
224
+ });
225
+ },
226
+ presentCall: (args) => ({
227
+ card: 'generic',
228
+ title: `Scaffold wiki vault (${args.template ?? 'default'})`,
229
+ kind: 'other',
230
+ rawInput: { template: args.template, apply: args.apply },
231
+ }),
232
+ });
233
+ // wiki_list
234
+ reg(ctx, {
235
+ name: 'wiki_list',
236
+ description: 'List all page titles in the vault (excluding machinery pages).',
237
+ parameters: {},
238
+ output: {
239
+ schema: { type: 'object', additionalProperties: true },
240
+ render: (_args, value) => [{ type: 'text', text: renderList(value) }],
241
+ },
242
+ execute: async () => ({ titles: [...listAllTitles(layout.wikiDir)] }),
243
+ presentCall: () => ({ card: 'generic', title: 'List wiki pages', kind: 'read' }),
244
+ });
245
+ // ── skills ───────────────────────────────────────────────────────────────
246
+ const candidates = [join(__dirname, 'skills'), join(__dirname, '..', 'skills')];
247
+ const skillsDir = candidates.find(p => existsSync(p));
248
+ if (skillsDir) {
249
+ const registered = registerAllSkills(ctx, skillsDir);
250
+ ctx.logger.info(`dsh-obsidian: registered ${registered.length} skill(s): ${registered.join(', ')}`);
251
+ }
252
+ else {
253
+ ctx.logger.warn(`dsh-obsidian: no skills/ directory found (looked in ${candidates.join(', ')})`);
254
+ }
255
+ ctx.logger.info(`dsh-obsidian ready. vault=${config.vaultPath} wiki=${layout.wikiDir}`);
256
+ }
257
+ // ──────────────────────────────────────────────────────────────────────────────
258
+ // Render helpers — control what the model sees in tool output
259
+ // ──────────────────────────────────────────────────────────────────────────────
260
+ function capText(text, max) {
261
+ return text.length <= max ? text : `${text.slice(0, max)}\n… (truncated at ${max} characters)`;
262
+ }
263
+ function renderQuery(value) {
264
+ const v = value;
265
+ if (!v)
266
+ return 'wiki_query: no result';
267
+ if (v.mode === 'quick') {
268
+ const parts = [];
269
+ if (typeof v.hot === 'string' && v.hot.length > 0) {
270
+ parts.push(`--- wiki/hot.md (recent context cache) ---\n${capText(v.hot, 6000)}`);
271
+ }
272
+ if (typeof v.index === 'string' && v.index.length > 0) {
273
+ parts.push(`--- wiki/index.md (master catalog) ---\n${capText(v.index, 8000)}`);
274
+ }
275
+ if (parts.length === 0)
276
+ return 'wiki_query (quick): the vault has no hot.md or index.md yet';
277
+ return `wiki_query (quick): hot cache and master index follow. Read these before any page.\n\n${parts.join('\n\n')}`;
278
+ }
279
+ if (!Array.isArray(v.results))
280
+ return 'wiki_query: no result';
281
+ const lines = [
282
+ `wiki_query: ${v.results.length} of ${v.totalMatches ?? v.results.length} matching pages. Open a page with the fs read tool for full content.`,
283
+ ];
284
+ for (const hit of v.results) {
285
+ lines.push(`\n### ${hit.name}`);
286
+ lines.push(`path: ${hit.path} · score ${hit.score} · inbound ${hit.inbound.length}${hit.inbound.length > 0 ? ` (${hit.inbound.slice(0, 5).join(', ')})` : ''} · outbound ${hit.outbound.length}`);
287
+ if (hit.snippet)
288
+ lines.push(`> ${hit.snippet}`);
289
+ }
290
+ return capText(lines.join('\n'), 12000);
291
+ }
292
+ function renderWrite(args, value) {
293
+ const a = args;
294
+ const v = value;
295
+ if (!v)
296
+ return 'wiki_write: failed';
297
+ if (v.alreadyIngested === true) {
298
+ return `wiki_write: skipped ${a.title ?? ''} — source hash unchanged (pass force: true to re-write)`;
299
+ }
300
+ if (v.path) {
301
+ const action = v.created ? 'created' : 'updated';
302
+ const tail = Array.isArray(v.unresolvedLinks) && v.unresolvedLinks.length > 0
303
+ ? `\nwiki_write: note — ${v.unresolvedLinks.length} unresolved wikilink(s) in this page: ${v.unresolvedLinks.slice(0, 8).join(', ')}${v.unresolvedLinks.length > 8 ? ', …' : ''}. Create those pages or fix the targets.`
304
+ : '';
305
+ return `wiki_write: ${action} ${v.path}${tail}`;
306
+ }
307
+ return `wiki_write: skipped ${a.title ?? ''}`;
308
+ }
309
+ function renderRename(value) {
310
+ const v = value;
311
+ if (!v || !v.path)
312
+ return 'wiki_rename: failed';
313
+ return `wiki_rename: [[${v.from}]] → [[${v.to}]]`;
314
+ }
315
+ function renderLint(value) {
316
+ const v = value;
317
+ if (!v || !v.totals)
318
+ return 'wiki_lint: failed';
319
+ const t = v.totals;
320
+ const lines = [
321
+ `wiki_lint: ${t.error + t.warn + t.info} issues (${t.error} error, ${t.warn} warn, ${t.info} info)`,
322
+ `report: ${v.reportPath ?? '(not written)'}`,
323
+ ];
324
+ for (const i of (v.issues ?? []).slice(0, 60)) {
325
+ lines.push(`- [${i.severity}] ${i.category} · ${i.file}: ${i.message}${i.suggestion ? ' → ' + i.suggestion : ''}`);
326
+ }
327
+ if ((v.issues ?? []).length > 60)
328
+ lines.push(`… and ${(v.issues ?? []).length - 60} more (see the report file)`);
329
+ return lines.join('\n');
330
+ }
331
+ function renderScaffold(value) {
332
+ const v = value;
333
+ if (!v || !v.plan)
334
+ return 'wiki_scaffold: failed';
335
+ const p = v.plan;
336
+ if (v.applied) {
337
+ return `wiki_scaffold: created ${p.create.length} dirs, wrote ${p.write.length} files, skipped ${p.skipped.length} existing`;
338
+ }
339
+ return `wiki_scaffold (dry-run): would create ${p.create.length} dirs and write ${p.write.length} files. Pass apply: true to actually write.`;
340
+ }
341
+ function renderList(value) {
342
+ const v = value;
343
+ if (!v || !Array.isArray(v.titles))
344
+ return 'wiki_list: failed';
345
+ if (v.titles.length === 0)
346
+ return 'wiki_list: vault is empty';
347
+ return `wiki_list: ${v.titles.length} pages\n\n` + v.titles.map(t => `- [[${t}]]`).join('\n');
348
+ }
349
+ // default export for tooling that expects the module form
350
+ export default { name, inject, Config, apply };
351
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}