obsidian-lean-coder 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +11 -1
- package/bin/olc-setup.js +128 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,22 @@ All notable changes to OLC (Obsidian Lean Coder) are recorded here.
|
|
|
4
4
|
OLC is pre-release: versions are `0.x` until a controlled-testing release says otherwise.
|
|
5
5
|
`package.json` shipped `"private": true` through 0.1.0; the flag was removed at publish time with explicit user approval, and 0.1.0 is live as [`obsidian-lean-coder`](https://www.npmjs.com/package/obsidian-lean-coder). Publishing a new version is still a separate explicitly approved action, never automatic.
|
|
6
6
|
|
|
7
|
+
## [0.2.0] — 2026-10-13 — `olc-setup` resource installer
|
|
8
|
+
|
|
9
|
+
New `olc-setup setup [--project|--global]` command (run manually via `npx obsidian-lean-coder setup`
|
|
10
|
+
after install): copies the shipped agents/skills into OpenCode discovery paths —
|
|
11
|
+
`<cwd>/.opencode` (project, default) or `~/.config/opencode` (`$XDG_CONFIG_HOME/opencode` when set,
|
|
12
|
+
global; global use is allowed only for this plugin's own install). Missing directories are created;
|
|
13
|
+
existing OLC agent/skill files are overwritten with the package versions (a deliberate, narrow
|
|
14
|
+
exception to the create-only rule, scoped to the files this command owns — see README §2).
|
|
15
|
+
`--dry-run` previews without writing; `opencode.json` is never edited (manual snippet printed after
|
|
16
|
+
each run). Node builtins only, no runtime dependencies.
|
|
17
|
+
|
|
18
|
+
- **Verification:** 6 fixture tests (`tests/setup.test.ts`: create, skip/overwrite, dry-run,
|
|
19
|
+
global scope, usage errors, mkdir -p); full suite 146/146 pass; typecheck/build clean.
|
|
20
|
+
- **Upgrade:** `npm install obsidian-lean-coder@0.2.0`, then `npx obsidian-lean-coder setup`
|
|
21
|
+
(add `--global` for global scope).
|
|
22
|
+
|
|
7
23
|
## [0.1.1] — 2026-10-13 — plugin entrypoint fix
|
|
8
24
|
|
|
9
25
|
Fixes npm-package activation (reported: `npm install` worked but nothing appeared in OpenCode).
|
package/README.md
CHANGED
|
@@ -67,7 +67,17 @@ printf '%s\n' '{ "type": "module", "dependencies": { "@opencode/plugin": "2.0.27
|
|
|
67
67
|
|
|
68
68
|
Verify with the same `grep` as above, expecting `.opencode/plugins/olc/index.js` in the loading line.
|
|
69
69
|
|
|
70
|
-
Then
|
|
70
|
+
Then install the agent/skill resources — recommended via the setup helper:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
npx obsidian-lean-coder setup # project scope: ./.opencode
|
|
74
|
+
npx obsidian-lean-coder setup --global # global scope: ~/.config/opencode
|
|
75
|
+
npx obsidian-lean-coder setup --dry-run # preview, writes nothing
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Missing directories are created; existing OLC agent/skill files are overwritten with the package
|
|
79
|
+
versions (a deliberate exception to the create-only rule, scoped to these files only).
|
|
80
|
+
Manual equivalent (DECISIONS.md #2 — programmatic registration was rejected for MVP):
|
|
71
81
|
|
|
72
82
|
```sh
|
|
73
83
|
PKG=/home/you/olc # your OLC checkout
|
package/bin/olc-setup.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* OLC setup helper (OLC-075).
|
|
4
|
+
*
|
|
5
|
+
* Manually run after `npm install -g obsidian-lean-coder` (or npx):
|
|
6
|
+
* olc-setup setup [--project|--global] [--dry-run]
|
|
7
|
+
*
|
|
8
|
+
* Copies the shipped agent/skill resources into OpenCode's discovery paths:
|
|
9
|
+
* project scope (default): <cwd>/.opencode/{agents,skills}
|
|
10
|
+
* global scope: ~/.config/opencode/{agents,skills}
|
|
11
|
+
* ($XDG_CONFIG_HOME/opencode when set)
|
|
12
|
+
*
|
|
13
|
+
* Behavior (locked with the user):
|
|
14
|
+
* - Missing directories are created (mkdir -p).
|
|
15
|
+
* - Existing OLC agent/skill files are OVERWRITTEN with the package
|
|
16
|
+
* versions. This is a deliberate, narrow exception to OLC's usual
|
|
17
|
+
* create-only rule — and it applies ONLY to the files this command owns
|
|
18
|
+
* (listed in OWNED_FILES below). Nothing else is touched.
|
|
19
|
+
* - `--dry-run` prints what would happen and writes nothing.
|
|
20
|
+
* - `opencode.json` is NEVER edited by this command. After it runs, it
|
|
21
|
+
* prints the manual plugin-registration snippet for README §2.
|
|
22
|
+
*
|
|
23
|
+
* Node builtins only — no runtime dependencies.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
27
|
+
import { dirname, join, resolve } from "node:path";
|
|
28
|
+
import { homedir } from "node:os";
|
|
29
|
+
import { fileURLToPath } from "node:url";
|
|
30
|
+
|
|
31
|
+
/** Files this command owns: [package-relative source, scope-relative dest]. */
|
|
32
|
+
const OWNED_FILES = [
|
|
33
|
+
["agents/olc-plan.md", ".opencode/agents/olc-plan.md"],
|
|
34
|
+
["agents/olc-build.md", ".opencode/agents/olc-build.md"],
|
|
35
|
+
["skills/olc-explore/SKILL.md", ".opencode/skills/olc-explore/SKILL.md"],
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
function usage() {
|
|
39
|
+
return [
|
|
40
|
+
"Usage: olc-setup setup [--project|--global] [--dry-run]",
|
|
41
|
+
"",
|
|
42
|
+
" setup copy shipped agents/skills into OpenCode discovery paths",
|
|
43
|
+
" --project install into <cwd>/.opencode (default)",
|
|
44
|
+
" --global install into ~/.config/opencode ($XDG_CONFIG_HOME/opencode when set)",
|
|
45
|
+
" --dry-run print what would happen, write nothing",
|
|
46
|
+
"",
|
|
47
|
+
"Existing OLC agent/skill files are overwritten with the package versions;",
|
|
48
|
+
"nothing else is touched, and opencode.json is never edited (see the",
|
|
49
|
+
"manual plugin-registration snippet printed after a successful run).",
|
|
50
|
+
].join("\n");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function fail(message) {
|
|
54
|
+
process.stderr.write(`olc-setup: ${message}\n${usage()}\n`);
|
|
55
|
+
process.exit(2);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function parseArgs(argv) {
|
|
59
|
+
if (argv[0] !== "setup") fail(`expected subcommand \"setup\", got ${JSON.stringify(argv[0] ?? "(none)")}.`);
|
|
60
|
+
let scope = "project";
|
|
61
|
+
let dryRun = false;
|
|
62
|
+
for (const arg of argv.slice(1)) {
|
|
63
|
+
if (arg === "--project") scope = "project";
|
|
64
|
+
else if (arg === "--global") scope = "global";
|
|
65
|
+
else if (arg === "--dry-run") dryRun = true;
|
|
66
|
+
else fail(`unknown argument ${JSON.stringify(arg)}.`);
|
|
67
|
+
}
|
|
68
|
+
return { scope, dryRun };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function packageRoot() {
|
|
72
|
+
return resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function scopeRoot(scope) {
|
|
76
|
+
if (scope === "project") return resolve(process.cwd());
|
|
77
|
+
const base = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
|
|
78
|
+
return resolve(base, "opencode");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function main() {
|
|
82
|
+
const { scope, dryRun } = parseArgs(process.argv.slice(2));
|
|
83
|
+
const pkg = packageRoot();
|
|
84
|
+
const root = scopeRoot(scope);
|
|
85
|
+
|
|
86
|
+
const missing = OWNED_FILES.map(([src]) => src).filter((src) => !existsSync(join(pkg, src)));
|
|
87
|
+
if (missing.length > 0) {
|
|
88
|
+
process.stderr.write(
|
|
89
|
+
`olc-setup: installed package is incomplete, missing: ${missing.join(", ")}. Reinstall obsidian-lean-coder.\n`,
|
|
90
|
+
);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const summary = [];
|
|
95
|
+
for (const [src, destRel] of OWNED_FILES) {
|
|
96
|
+
const dest = join(root, destRel);
|
|
97
|
+
const wanted = readFileSync(join(pkg, src), "utf8");
|
|
98
|
+
const prior = existsSync(dest) ? readFileSync(dest, "utf8") : null;
|
|
99
|
+
if (prior === wanted) {
|
|
100
|
+
summary.push({ file: destRel, action: "skipped" });
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (!dryRun) {
|
|
104
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
105
|
+
writeFileSync(dest, wanted, "utf8");
|
|
106
|
+
}
|
|
107
|
+
summary.push({ file: destRel, action: prior === null ? "created" : "overwritten" });
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const counts = { created: 0, overwritten: 0, skipped: 0 };
|
|
111
|
+
for (const entry of summary) {
|
|
112
|
+
counts[entry.action] += 1;
|
|
113
|
+
process.stdout.write(`${entry.action} ${entry.file}\n`);
|
|
114
|
+
}
|
|
115
|
+
process.stdout.write(
|
|
116
|
+
`${dryRun ? "[dry-run] " : ""}done (${scope} scope, ${root}): ` +
|
|
117
|
+
`${counts.created} created, ${counts.overwritten} overwritten, ${counts.skipped} skipped.\n`,
|
|
118
|
+
);
|
|
119
|
+
if (!dryRun) {
|
|
120
|
+
process.stdout.write(
|
|
121
|
+
"\nNext (manual): register the plugin in opencode.json so OpenCode loads it:\n" +
|
|
122
|
+
' { "plugins": ["obsidian-lean-coder"] }\n' +
|
|
123
|
+
"See README §2 for verification. opencode.json was left untouched.\n",
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
main();
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "obsidian-lean-coder",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Obsidian Lean Coder — OpenCode extension for project-scoped planning, memory, and safe Git checkpoints.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"olc-setup": "./bin/olc-setup.js"
|
|
9
|
+
},
|
|
7
10
|
"types": "./dist/index.d.ts",
|
|
8
11
|
"exports": {
|
|
9
12
|
".": {
|
|
@@ -16,6 +19,7 @@
|
|
|
16
19
|
"agents",
|
|
17
20
|
"skills",
|
|
18
21
|
"templates",
|
|
22
|
+
"bin",
|
|
19
23
|
"README.md",
|
|
20
24
|
"CHANGELOG.md"
|
|
21
25
|
],
|