obsidian-lean-coder 0.4.1 → 0.5.1
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 +38 -0
- package/README.md +82 -82
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/init/index.js +4 -2
- package/dist/log/index.js +8 -1
- package/dist/planning/index.js +4 -1
- package/package.json +1 -1
- package/skills/olc-explore/SKILL.md +21 -21
- package/skills/olc-init/SKILL.md +25 -24
- package/skills/olc-log/SKILL.md +14 -14
- package/skills/olc-memory/SKILL.md +14 -14
- package/skills/olc-taste/SKILL.md +14 -14
- package/templates/activity-log.md +5 -0
- package/templates/checkpoint.md +6 -0
- package/templates/decision.md +4 -0
- package/templates/explore-report.md +6 -0
- package/templates/intent.md +6 -0
- package/templates/plan.md +7 -0
- package/templates/taste-rule.md +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,44 @@ 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.5.1] — 2026-10-14 — English skill docs, concise install instructions
|
|
8
|
+
|
|
9
|
+
All 5 bundled skills (`olc-log`, `olc-explore`, `olc-init`, `olc-memory`,
|
|
10
|
+
`olc-taste`) are now written in English; code identifiers, paths, and
|
|
11
|
+
examples are unchanged. The README's install section is now a 3-command
|
|
12
|
+
quick start right under the brief, instead of a long three-step walkthrough;
|
|
13
|
+
the previous detailed content (dev install path, plugin activation, API
|
|
14
|
+
caveats) is preserved under a new `## Reference` section.
|
|
15
|
+
|
|
16
|
+
- **Verification:** typecheck/build clean; full suite green (152 tests,
|
|
17
|
+
no test changes needed — docs-only); `npm pack --dry-run` file check.
|
|
18
|
+
- **Upgrade:** `npm install obsidian-lean-coder@0.5.1`. No vault or config
|
|
19
|
+
changes required.
|
|
20
|
+
|
|
21
|
+
## [0.5.0] — 2026-10-14 — vault cross-linking for the second-brain graph
|
|
22
|
+
|
|
23
|
+
Vault documents were isolated islands: no `[[wikilinks]]` connected intent to
|
|
24
|
+
plan, checkpoints to history, or the daily log to the task it recorded. Since
|
|
25
|
+
the vault is meant as the project's second brain, every bundled template now
|
|
26
|
+
ships a `## Terkait` section with relative wikilinks to its natural
|
|
27
|
+
neighbours (intent ↔ plan ↔ history ↔ checkpoint; explore reports and taste
|
|
28
|
+
rules back to the project hub; daily logs to the hub and, per entry, to the
|
|
29
|
+
task it concerns). `index.md` and `current-state.md` link to each other.
|
|
30
|
+
`decision.md` takes a new `related` variable so its links reflect the actual
|
|
31
|
+
decision (callers must supply it). `session-summary.md` stays link-free by
|
|
32
|
+
design — it has no fixed vault location, so it is returned in chat, never
|
|
33
|
+
written to a file.
|
|
34
|
+
|
|
35
|
+
This only affects newly rendered documents; pre-existing vault files from
|
|
36
|
+
earlier versions are not backfilled.
|
|
37
|
+
|
|
38
|
+
- **Verification:** typecheck/build clean; full suite green (152 tests,
|
|
39
|
+
including a new end-to-end fixture that walks every markdown file in a
|
|
40
|
+
generated vault and resolves every `[[...]]` target on disk);
|
|
41
|
+
`npm pack --dry-run` file check.
|
|
42
|
+
- **Upgrade:** `npm install obsidian-lean-coder@0.5.0`, then re-run any task
|
|
43
|
+
that still needs its docs drafted — existing docs keep their old content.
|
|
44
|
+
|
|
7
45
|
## [0.4.1] — 2026-10-14 — verification tooling rule for minimal harnesses
|
|
8
46
|
|
|
9
47
|
`agents/olc-build.md` gains a verification rule from a real field report: prefer
|
package/README.md
CHANGED
|
@@ -1,119 +1,119 @@
|
|
|
1
1
|
# OLC — Obsidian Lean Coder
|
|
2
2
|
|
|
3
|
-
OpenCode extension for project-scoped planning, memory, and safe Git checkpoints. On npm as `obsidian-lean-coder` (v0.
|
|
3
|
+
OpenCode extension for project-scoped planning, memory, and safe Git checkpoints. On npm as `obsidian-lean-coder` (v0.5.1: English skill docs, concise install — see CHANGELOG).
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
Do not confuse these. They are different operations with different commands:
|
|
8
|
-
|
|
9
|
-
| # | Step | What it does | Command |
|
|
10
|
-
|---|------|--------------|---------|
|
|
11
|
-
| 1 | **Dev install** | Install npm deps to hack on OLC itself | `npm ci && npm run build` |
|
|
12
|
-
| 2 | **Plugin activation** | Load OLC as an OpenCode plugin | `npm i obsidian-lean-coder` + `opencode.json` snippet below |
|
|
13
|
-
| 3 | **Project init** | Register one app repo + vault with OLC (`initProject`, idempotent, create-only) | via the `olc-init` skill in OpenCode (the tested path) |
|
|
14
|
-
|
|
15
|
-
## 1. Dev install
|
|
16
|
-
|
|
17
|
-
Requirements: Node >= 18.18, npm, git.
|
|
18
|
-
|
|
19
|
-
```sh
|
|
20
|
-
git clone <this-repo> olc && cd olc
|
|
21
|
-
npm ci
|
|
22
|
-
npm run build # tsc -p tsconfig.json → dist/
|
|
23
|
-
npm test # tsc -p tsconfig.tests.json && node --test "dist-tests/tests/**/*.test.js"
|
|
24
|
-
npm run typecheck
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Expected: build clean, typecheck clean. `npm test` runs the full suite (currently 146 tests). `npm pack --dry-run` shows what would ship (`dist/`, `agents/`, `skills/`, `templates/`).
|
|
28
|
-
|
|
29
|
-
> Published on npm as `obsidian-lean-coder` (MIT). Republishing needs a separate explicit approval — never publish by accident.
|
|
30
|
-
|
|
31
|
-
## 2. Plugin activation
|
|
5
|
+
## Install
|
|
32
6
|
|
|
33
7
|
```sh
|
|
34
8
|
npm install obsidian-lean-coder
|
|
35
9
|
```
|
|
36
10
|
|
|
37
|
-
|
|
11
|
+
Add it to your project's `opencode.json`:
|
|
38
12
|
|
|
39
13
|
```json
|
|
40
|
-
{
|
|
41
|
-
"plugins": ["obsidian-lean-coder"]
|
|
42
|
-
}
|
|
14
|
+
{ "plugins": ["obsidian-lean-coder"] }
|
|
43
15
|
```
|
|
44
16
|
|
|
45
|
-
|
|
17
|
+
Copy the agents/skills into `.opencode/` (idempotent — safe to re-run after upgrading):
|
|
46
18
|
|
|
47
19
|
```sh
|
|
48
|
-
|
|
20
|
+
npx obsidian-lean-coder setup
|
|
49
21
|
```
|
|
50
22
|
|
|
51
|
-
|
|
23
|
+
Then open OpenCode in the project and run the **olc-init** skill to register the repo with a vault — that's it. Everything below is reference detail (requirements, what each step actually does, uninstall, troubleshooting).
|
|
52
24
|
|
|
53
|
-
|
|
25
|
+
Requirements: OpenCode 2.x (V2 plugin API), Node >= 18.18.
|
|
54
26
|
|
|
55
|
-
|
|
27
|
+
## Reference
|
|
56
28
|
|
|
57
|
-
|
|
29
|
+
### What `npx obsidian-lean-coder setup` does
|
|
58
30
|
|
|
59
|
-
|
|
31
|
+
Installs `agents/olc-plan.md`, `agents/olc-build.md`, and the five skills
|
|
32
|
+
(`olc-init`, `olc-explore`, `olc-memory`, `olc-log`, `olc-taste`) under
|
|
33
|
+
`.opencode/` (project scope by default). `--global` installs under
|
|
34
|
+
`~/.config/opencode` instead; `--dry-run` previews with no writes. Missing
|
|
35
|
+
directories are created; existing OLC agent/skill files are overwritten with
|
|
36
|
+
the package versions (a deliberate exception to the create-only rule, scoped
|
|
37
|
+
to these files only — your own vault notes are never touched by this).
|
|
60
38
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
```
|
|
39
|
+
Both agents behave exactly like OpenCode's default Plan/Build agents first,
|
|
40
|
+
then add OLC rules: each session they read the project root `AGENTS.md` (if
|
|
41
|
+
present) and `.olc/AGENTS.md` (if present). If the two disagree, the OpenCode
|
|
42
|
+
default wins — the agent shows the conflict, suggests a fix, and stops for
|
|
43
|
+
your choice.
|
|
67
44
|
|
|
68
|
-
|
|
45
|
+
### What `olc-init` does
|
|
69
46
|
|
|
70
|
-
|
|
47
|
+
`initProject` (`src/init/index.ts`) registers one app repo + vault. It is
|
|
48
|
+
idempotent and **create-only**: existing files are reported `preserved`,
|
|
49
|
+
never overwritten. Anything needing a human choice comes back as
|
|
50
|
+
`status: "needs-decision"` — no prompting inside the module. During init you
|
|
51
|
+
are asked whether the project has extra rules beyond the main agents file;
|
|
52
|
+
confirmed additions go under "Additional project rules" in `.olc/AGENTS.md`.
|
|
71
53
|
|
|
72
|
-
|
|
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
|
-
```
|
|
54
|
+
What it creates (only when missing):
|
|
77
55
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
56
|
+
- `<repo>/.olc/config.json` — `{ schemaVersion, projectId, vaultPath }`. No secrets (keys matching `secret|token|password|api-key` are rejected).
|
|
57
|
+
- `<repo>/.olc/AGENTS.md` — stub instructions for agents. Review and customize.
|
|
58
|
+
- `<vault>/OLC/Projects/<project_id>/{index.md, current-state.md, decisions/, tasks/, logs/, memory/, taste/}`
|
|
59
|
+
- `<vault>/OLC/registry.json` — `{ projects: { "<id>": { repoRoot } } }` entry for this repo.
|
|
81
60
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
for s in olc-init olc-explore olc-memory olc-log olc-taste; do cp "$PKG"/skills/$s/SKILL.md .opencode/skills/$s/; done
|
|
87
|
-
```
|
|
61
|
+
Vault path precedence: explicit `vaultPath` > `OLC_VAULT_PATH` env > existing
|
|
62
|
+
config. OLC never invents a vault location — missing path returns
|
|
63
|
+
`needs-decision`, never a silent default. Re-running init is always safe:
|
|
64
|
+
`created` becomes `preserved`.
|
|
88
65
|
|
|
89
|
-
|
|
66
|
+
### Contributing to OLC itself
|
|
90
67
|
|
|
91
68
|
```sh
|
|
92
|
-
|
|
69
|
+
git clone <this-repo> olc && cd olc
|
|
70
|
+
npm ci
|
|
71
|
+
npm run build # tsc -p tsconfig.json → dist/
|
|
72
|
+
npm test # tsc -p tsconfig.tests.json && node --test "dist-tests/tests/**/*.test.js"
|
|
73
|
+
npm run typecheck
|
|
93
74
|
```
|
|
94
75
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
76
|
+
Expected: build clean, typecheck clean, full suite green (currently 152
|
|
77
|
+
tests). `npm pack --dry-run` shows what would ship (`dist/`, `agents/`,
|
|
78
|
+
`skills/`, `templates/`).
|
|
98
79
|
|
|
99
|
-
|
|
80
|
+
A local checkout can be loaded without publishing: `.opencode/plugins/<name>/index.js`
|
|
81
|
+
re-exporting `file://<checkout>/dist/plugin.js` auto-loads with no install
|
|
82
|
+
step. See `docs/DECISIONS.md` and `docs/TASKS.md` for the full history if you
|
|
83
|
+
need it.
|
|
100
84
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
`initProject` (`src/init/index.ts`) registers one app repo + vault. It is idempotent and **create-only**: existing files are reported `preserved`, never overwritten. Anything needing a human choice comes back as `status: "needs-decision"` — no prompting inside the module.
|
|
104
|
-
|
|
105
|
-
Run it via the `olc-init` skill inside OpenCode (recommended — the only tested path for MVP). A programmatic import is not yet wired: the package entrypoint (`dist/index.js`) exports `OLC_VERSION` plus the plugin default, and `initProject` lives in `src/init/index.ts` for internal/agent use.
|
|
106
|
-
|
|
107
|
-
What it creates (only when missing):
|
|
108
|
-
|
|
109
|
-
- `<repo>/.olc/config.json` — `{ schemaVersion, projectId, vaultPath }`. No secrets (keys matching `secret|token|password|api-key` are rejected).
|
|
110
|
-
- `<repo>/.olc/AGENTS.md` — stub instructions for agents. Review and customize.
|
|
111
|
-
- `<vault>/OLC/Projects/<project_id>/{index.md, current-state.md, decisions/, tasks/, logs/, memory/, taste/}`
|
|
112
|
-
- `<vault>/OLC/registry.json` — `{ projects: { "<id>": { repoRoot } } }` entry for this repo.
|
|
113
|
-
|
|
114
|
-
Vault path precedence: explicit `vaultPath` > `OLC_VAULT_PATH` env > existing config. OLC never invents a vault location — missing path returns `needs-decision`, never a silent default.
|
|
85
|
+
> Published on npm as `obsidian-lean-coder` (MIT). Republishing needs a separate explicit approval — never publish by accident.
|
|
115
86
|
|
|
116
|
-
|
|
87
|
+
### Vault linking rules (second brain)
|
|
88
|
+
|
|
89
|
+
The vault is meant as the project's long-term memory, so every document a
|
|
90
|
+
template produces must be a node in Obsidian's link graph, not an isolated
|
|
91
|
+
file. Rules:
|
|
92
|
+
|
|
93
|
+
- Every bundled template carries a `## Terkait` section with **relative**
|
|
94
|
+
`[[wikilinks]]` to its natural neighbours — e.g. `intent.md` ↔ `plan.md` ↔
|
|
95
|
+
`history.md` ↔ `checkpoint.md`; `explore-report.md` and `taste-rule.md`
|
|
96
|
+
back to the project hub (`index.md`, `current-state.md`); each daily log
|
|
97
|
+
file links to the hub, and each logged event with a `taskId` links to that
|
|
98
|
+
task's `intent.md`/`plan.md`.
|
|
99
|
+
- `index.md` and `current-state.md` link to each other — they are the hub a
|
|
100
|
+
reader lands on first.
|
|
101
|
+
- Links are relative path-form (`[[../T-1/plan]]`, not a bare `[[plan]]`),
|
|
102
|
+
so they resolve correctly whether Obsidian's vault root is `<vault>` or
|
|
103
|
+
`<vault>/OLC/Projects/<id>`, and stay correct across multiple projects
|
|
104
|
+
sharing one vault (a bare `[[plan]]` would be ambiguous between projects).
|
|
105
|
+
- `decision.md` takes a `related` template variable — the caller supplies
|
|
106
|
+
the links relevant to that specific decision; there is no fixed set.
|
|
107
|
+
- `session-summary.md` is the one exception: it has no fixed vault location
|
|
108
|
+
(it's returned in chat for the user to read, never written to a file), so
|
|
109
|
+
it carries no links by design.
|
|
110
|
+
- **Limitation:** linking only applies to newly rendered documents. Older
|
|
111
|
+
vault files written by a previous OLC version are not backfilled with
|
|
112
|
+
links (see D-005 in `docs/TASKS.md`).
|
|
113
|
+
- Writing to `memory/<name>.md` via the `olc-memory` skill is free-form
|
|
114
|
+
(no template), but should still include a `## Terkait` section linking
|
|
115
|
+
back to `[[../index]]`/`[[../current-state]]` and any related task or
|
|
116
|
+
decision, to keep the memory graph connected.
|
|
117
117
|
|
|
118
118
|
## Updating
|
|
119
119
|
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/init/index.js
CHANGED
|
@@ -26,8 +26,10 @@ const AGENTS_STUB = (projectId) => `# OLC project instructions — ${projectId}\
|
|
|
26
26
|
"Bila bertentangan dengan perilaku default OpenCode, default yang menang — agen akan\n" +
|
|
27
27
|
"menunjukkan konfliknya dan meminta keputusan Anda sebelum lanjut.\n\n" +
|
|
28
28
|
"- (belum ada — tambahkan sesuai kebutuhan proyek)\n";
|
|
29
|
-
const VAULT_INDEX = (projectId) => `# ${projectId}\n\nOLC project memory root. See current-state.md for the latest status.\n
|
|
30
|
-
|
|
29
|
+
const VAULT_INDEX = (projectId) => `# ${projectId}\n\nOLC project memory root. See current-state.md for the latest status.\n` +
|
|
30
|
+
`\n## Terkait\n\n- [[current-state]] — status terbaru proyek\n`;
|
|
31
|
+
const VAULT_STATE = (projectId) => `# Current state — ${projectId}\n\nInitialized. No activity recorded yet.\n` +
|
|
32
|
+
`\n## Terkait\n\n- [[index]] — hub memori proyek\n`;
|
|
31
33
|
/** Derive a safe project_id proposal from the repository directory name. */
|
|
32
34
|
export function proposeProjectId(repoRoot) {
|
|
33
35
|
const cleaned = basename(resolve(repoRoot))
|
package/dist/log/index.js
CHANGED
|
@@ -70,7 +70,8 @@ function ensureDayFile(path, projectId, day) {
|
|
|
70
70
|
// "wx" fails when another process won the race — that is fine, the file
|
|
71
71
|
// (with an identical header) already exists and we just append below.
|
|
72
72
|
try {
|
|
73
|
-
const header = withFrontmatter({ project: projectId, type: "activity-log", date: day }, "")
|
|
73
|
+
const header = withFrontmatter({ project: projectId, type: "activity-log", date: day }, "") +
|
|
74
|
+
"## Terkait\n\n- [[../index]] — hub memori proyek\n- [[../current-state]] — status terbaru proyek\n\n";
|
|
74
75
|
appendFileSync(path, header.endsWith("\n") ? header : header + "\n", { flag: "wx" });
|
|
75
76
|
}
|
|
76
77
|
catch (error) {
|
|
@@ -91,6 +92,12 @@ function formatEntry(event, iso) {
|
|
|
91
92
|
lines.push(`- sha: ${event.gitSha}`);
|
|
92
93
|
if (redacted)
|
|
93
94
|
lines.push(`- redacted: true`);
|
|
95
|
+
// Obsidian graph links toward the task docs. parseEntries does not know the
|
|
96
|
+
// `terkait` key and safely ignores it; it exists purely so every log entry
|
|
97
|
+
// is a clickable node in the vault graph (second-brain navigation).
|
|
98
|
+
if (event.taskId) {
|
|
99
|
+
lines.push(`- terkait: [[../tasks/${event.taskId}/intent]], [[../tasks/${event.taskId}/plan]]`);
|
|
100
|
+
}
|
|
94
101
|
return lines.join("\n") + "\n";
|
|
95
102
|
}
|
|
96
103
|
/**
|
package/dist/planning/index.js
CHANGED
|
@@ -112,7 +112,10 @@ function appendHistory(vaultRoot, projectId, taskId, kind, reason, date) {
|
|
|
112
112
|
existing = "";
|
|
113
113
|
}
|
|
114
114
|
const entry = `## ${date} — ${kind}\n\n${reason}\n`;
|
|
115
|
-
|
|
115
|
+
const header = `# History — ${taskId}\n\n## Terkait\n\n` +
|
|
116
|
+
`- [[../${taskId}/intent]] — maksud kerja\n` +
|
|
117
|
+
`- [[../${taskId}/plan]] — rencana kerja\n\n`;
|
|
118
|
+
writeVaultDoc(history, existing === "" ? `${header}${entry}` : `${existing}\n${entry}`, {
|
|
116
119
|
overwrite: true,
|
|
117
120
|
});
|
|
118
121
|
}
|
package/package.json
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: olc-explore
|
|
3
|
-
description:
|
|
3
|
+
description: Investigate a complex/uncertain request before planning. Read-only against app code; produces a single exploration report in the vault.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# olc-explore
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
Clarify a complex or uncertain request **before** `intent.md`/`plan.md` are created.
|
|
9
|
+
For simple, already-clear tasks, skip this skill and go straight to Plan (direct Plan).
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## When to use vs direct Plan
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
13
|
+
- Use Explore when: the request is ambiguous, touches unfamiliar territory, has multiple approaches with real tradeoffs, or carries a high risk of misunderstanding.
|
|
14
|
+
- Use direct Plan when: the change is small and localized, the approach is already clear, there are no material open questions.
|
|
15
|
+
- The user's choice wins: if the user asks for direct Plan, don't force Explore, and vice versa.
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## Hard rules
|
|
18
18
|
|
|
19
|
-
1. **Read-only
|
|
20
|
-
2.
|
|
21
|
-
3.
|
|
22
|
-
4.
|
|
19
|
+
1. **Read-only against app source.** Allowed: reading files, running read-only commands (status, log, read-only tests), tracing code. FORBIDDEN: changing, adding, or removing app files in any way — no "while I'm at it" fixes, no small refactors.
|
|
20
|
+
2. One active report per task: `tasks/<task-id>/explore/report.md` in the already-validated project vault (OLC-021). Do not create a competing report file.
|
|
21
|
+
3. Every finding claim needs evidence: a file path + line, command output, or a config quote. No evidence = open question, not a finding.
|
|
22
|
+
4. Revisions never erase important reasoning: a revision is added as a new dated section in the same report; the reason for the approach change must be recorded.
|
|
23
23
|
|
|
24
|
-
##
|
|
24
|
+
## Flow
|
|
25
25
|
|
|
26
|
-
1.
|
|
27
|
-
2.
|
|
28
|
-
3.
|
|
29
|
-
4.
|
|
30
|
-
5.
|
|
26
|
+
1. Validate project identity and read `project_id` from `.olc/config.json` (no vault operation passes before this).
|
|
27
|
+
2. Read the user's request plus just enough relevant context (vault index/current-state if present, related app files). Do not read the entire vault.
|
|
28
|
+
3. Write the report via the `explore-report` template (vars: `task_id`, `project_id`, `date`, `request`, `findings`, `options`, `recommendation`). Create the `explore/` directory if missing; never overwrite an already-customized report without approval (follow OLC-023's create-only rule).
|
|
29
|
+
4. If the request changes or new findings appear: add a new dated revision section to the same report, record the reason in the task's `history.md`.
|
|
30
|
+
5. Hand off to Plan: the explore report is input to `draftTaskDocs`, not a replacement for `intent.md`/`plan.md`. No coding happens until both documents are approved (OLC-032).
|
|
31
31
|
|
|
32
|
-
##
|
|
32
|
+
## Verifying this skill
|
|
33
33
|
|
|
34
|
-
-
|
|
35
|
-
-
|
|
34
|
+
- After Explore: `git status --short` in the app repo must be clean (no app changes).
|
|
35
|
+
- The report exists at the correct path and every template var is filled (no leftover `{{...}}`).
|
package/skills/olc-init/SKILL.md
CHANGED
|
@@ -1,39 +1,40 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: olc-init
|
|
3
|
-
description:
|
|
3
|
+
description: Safely and idempotently register one app repo + vault with OLC. Create-only — never overwrites existing files.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# olc-init
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Initialize an OLC project: propose a `project_id`, confirm the vault path, set up `.olc/` and the vault structure, then register the repo↔vault pair in the registry.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Hard rules
|
|
11
11
|
|
|
12
|
-
1. **
|
|
13
|
-
2. **Create-only.**
|
|
14
|
-
3. **
|
|
15
|
-
4. **
|
|
12
|
+
1. **Explain before writing.** State which files will be created before calling `initProject`.
|
|
13
|
+
2. **Create-only.** Existing files are reported as `preserved` — never overwritten. Anything needing a human decision comes back as `status: "needs-decision"` with an actionable message.
|
|
14
|
+
3. **No guessing the vault.** Precedence: explicit `vaultPath` > env `OLC_VAULT_PATH` > existing config. If none exist, ask the user — never silently create a default location.
|
|
15
|
+
4. **No prompting inside the module.** Gather answers first, then call again with the full parameters.
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## Flow
|
|
18
18
|
|
|
19
|
-
1.
|
|
20
|
-
2.
|
|
21
|
-
3.
|
|
22
|
-
4.
|
|
23
|
-
AGENTS.md
|
|
24
|
-
`<repo>/.olc/AGENTS.md` (file
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
5.
|
|
19
|
+
1. Call `initProject({ projectRoot })` — get a proposed `project_id` (sanitized derivative of the repo name).
|
|
20
|
+
2. If `status: "needs-decision"`, ask the user: confirm `projectId`, fill in `vaultPath`, or resolve a duplicate id per the message.
|
|
21
|
+
3. Call again with `{ projectRoot, projectId, vaultPath }` until `status: "ready"`.
|
|
22
|
+
4. Ask the user: "Are there any additional project rules beyond what's in the
|
|
23
|
+
main AGENTS.md?" If yes, write them to the "Additional project rules"
|
|
24
|
+
section of `<repo>/.olc/AGENTS.md` (that file is create-only — if it
|
|
25
|
+
already exists and already has rules, don't overwrite; merge only if the
|
|
26
|
+
user asks).
|
|
27
|
+
5. Report a `created` / `preserved` / `attention` summary to the user in plain language.
|
|
28
|
+
5. To preview without writing: `initProject({ ..., dryRun: true })` — `created` means "would be created".
|
|
28
29
|
|
|
29
|
-
##
|
|
30
|
+
## What gets created (only if missing)
|
|
30
31
|
|
|
31
|
-
- `<repo>/.olc/config.json` — `{ schemaVersion, projectId, vaultPath }`.
|
|
32
|
-
- `<repo>/.olc/AGENTS.md` — stub
|
|
32
|
+
- `<repo>/.olc/config.json` — `{ schemaVersion, projectId, vaultPath }`. Keys that look like credentials (`secret|token|password|api-key`) are rejected.
|
|
33
|
+
- `<repo>/.olc/AGENTS.md` — instruction stub, asks the user to review and adjust.
|
|
33
34
|
- `<vault>/OLC/Projects/<project_id>/{index.md, current-state.md, decisions/, tasks/, logs/, memory/, taste/}`
|
|
34
|
-
-
|
|
35
|
+
- An entry `{ projects: { "<id>": { repoRoot } } }` in `<vault>/OLC/registry.json`.
|
|
35
36
|
|
|
36
|
-
##
|
|
37
|
+
## Verifying this skill
|
|
37
38
|
|
|
38
|
-
-
|
|
39
|
-
- Init
|
|
39
|
+
- Run init twice against a temporary fixture repo/vault: the second run is all `preserved`, no byte changes.
|
|
40
|
+
- Init with existing config + custom instructions: the custom file stays byte-identical.
|
package/skills/olc-log/SKILL.md
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: olc-log
|
|
3
|
-
description:
|
|
3
|
+
description: Record important events, checkpoints, and session summaries into a durable daily activity log. Verified crash-safe and secret-leak-safe.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# olc-log
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Durable per-project activity log at `<vault>/OLC/Projects/<project_id>/logs/YYYY-MM-DD.md` (one file per day — that's its only rotation, no size-based rotation for MVP).
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Hard rules
|
|
11
11
|
|
|
12
|
-
1. **
|
|
13
|
-
2. **
|
|
14
|
-
3. **
|
|
15
|
-
4. **
|
|
12
|
+
1. **Explicit events only.** The module never hooks tool calls — no per-tool-call noise by construction. Log only milestones, checkpoints, verifications, and session summaries.
|
|
13
|
+
2. **Secrets are redacted, never stored.** Known credential patterns in summary/details are replaced with `[redacted]` and the entry is flagged.
|
|
14
|
+
3. **Safe appends.** One `O_APPEND` write per entry; an interruption never corrupts earlier entries. A file missing its trailing newline (crash remnant) is normalized before the next append.
|
|
15
|
+
4. **Identity first.** Wrong vault → throw with zero files created.
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## Flow
|
|
18
18
|
|
|
19
|
-
1.
|
|
20
|
-
2.
|
|
21
|
-
3.
|
|
19
|
+
1. Write: `logEvent({ projectRoot, config, event: { kind, summary, taskId?, details?, gitSha?, date? } })` — `kind` e.g. `milestone|checkpoint|verify|session`; non-empty `summary` is required.
|
|
20
|
+
2. Read: `readLogDay(vaultRoot, projectId, day)` or `readLastEvents(vaultRoot, projectId, limit)` (newest first — the last verification shows up there).
|
|
21
|
+
3. Normal session end: call `buildSessionSummary` (module `session`) — rendered via the `session-summary` template with an honest hard-kill footer, factual claims sourced only from a real `VerifyOutcome`/SHA/checkpoint — then show it to the user. A session that dies abruptly produces no summary; the last log event is the recovery point (see resume).
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## Verifying this skill
|
|
24
24
|
|
|
25
|
-
-
|
|
26
|
-
-
|
|
25
|
+
- Secret patterns like `sk-...`, `ghp_...`, `AKIA...` in a summary never reach the vault (they become `[redacted]`).
|
|
26
|
+
- An interruption mid-append never corrupts earlier entries.
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: olc-memory
|
|
3
|
-
description:
|
|
3
|
+
description: Search and update project memory notes progressively — read small first, only what's relevant to the query. Never scans the whole vault.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# olc-memory
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Project-scoped memory: read `index.md` + `current-state.md` first, then only the `memory/` + `decisions/` documents, task docs, and log events relevant to the query. Write back only within the validated project scope.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Hard rules
|
|
11
11
|
|
|
12
|
-
1. **
|
|
13
|
-
2. **
|
|
14
|
-
3. **
|
|
12
|
+
1. **Identity first.** `validateIdentity` must pass before any read/write. Wrong project or unavailable vault → fail with zero files touched.
|
|
13
|
+
2. **Never scans other projects' folders.** Every path resolves inside `<vault>/OLC/Projects/<id>/`; other folders are untouched by construction.
|
|
14
|
+
3. **Controlled writes.** `recordMemory` requires a plain name (letters/digits/dash/underscore, no path/extension) plus non-empty content; existing files are never silently overwritten (`overwrite` must be explicit).
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## Flow
|
|
17
17
|
|
|
18
|
-
1.
|
|
19
|
-
2.
|
|
20
|
-
3.
|
|
21
|
-
4.
|
|
18
|
+
1. Call `recallMemory({ projectRoot, config, query?, taskId?, includeLogs?, logLimit?, limit? })` — no query = base context (index + state + recent log, unfiltered).
|
|
19
|
+
2. With a query: query tokens are filtered for stopwords, each `memory/` + `decisions/` document is scored (filename weighted), excerpts are capped at 1200 characters with a truncation flag, best score first.
|
|
20
|
+
3. With `taskId`: include that task's intent/plan doc status (missing → null, not an error).
|
|
21
|
+
4. To save: `recordMemory({ projectRoot, config, name, content, overwrite? })` → atomic write to `memory/<name>.md`. `content` must include a `## Terkait` section with relative wikilinks to `[[../index]]`, `[[../current-state]]`, and any related task/decision document — this keeps the memory note connected in the vault graph (second brain) instead of an isolated island.
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## Verifying this skill
|
|
24
24
|
|
|
25
|
-
-
|
|
26
|
-
-
|
|
25
|
+
- Project A's memory never shows up on recall in project B (multi-project isolation).
|
|
26
|
+
- Every relevance claim is traceable to a document + line, not invented.
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: olc-taste
|
|
3
|
-
description:
|
|
3
|
+
description: Learn project-specific preferences without silently changing behavior. Repeated signals become pending proposals; only user approval activates them.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# olc-taste
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Project taste is learned without silent behavior change: a repeated signal is recorded as a `pending` proposal complete with examples/evidence, and only an explicit user decision turns it `active`. Rejection parks it as `rejected` (kept as history, never used). A `pending` rule is never treated as active by any consumer.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Hard rules
|
|
11
11
|
|
|
12
|
-
1. **
|
|
13
|
-
2. **
|
|
14
|
-
3. **
|
|
12
|
+
1. **Only the user activates.** There is no automatic pending→active path. Review is terminal: `active`/`rejected` cannot be re-reviewed (`BAD_TRANSITION`).
|
|
13
|
+
2. **Single-project scope.** Every path lives inside the validated project's `taste/`; other projects are untouched. This module never touches `tasks/` — approved intent/plan can't be overwritten from here.
|
|
14
|
+
3. **Proposals need evidence.** Without ≥1 example/repeated signal, a proposal is rejected outright (`INVALID_INPUT`). Duplicates are never silently merged (`ALREADY_EXISTS`).
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## Flow
|
|
17
17
|
|
|
18
|
-
1.
|
|
19
|
-
2.
|
|
20
|
-
3.
|
|
18
|
+
1. Propose: `proposeTasteRule({ projectRoot, config, name, rule, examples[] })` → `taste/<name>.md` with status `pending`, via the `taste-rule` template, atomic create-only write.
|
|
19
|
+
2. Read: `getTasteRule(...)` / `listTasteRules({ status? })` — only within the validated scope, name-sorted.
|
|
20
|
+
3. Explicit review with the user: `reviewTasteRule({ projectRoot, config, name, approve })` — `true` = pending→active, `false` = pending→rejected. Unknown name → `UNKNOWN_RULE`.
|
|
21
21
|
|
|
22
|
-
##
|
|
22
|
+
## Verifying this skill
|
|
23
23
|
|
|
24
|
-
-
|
|
25
|
-
- `approve`
|
|
26
|
-
-
|
|
24
|
+
- A `pending` rule never appears in the `active` list.
|
|
25
|
+
- `approve` activates, `reject` parks; re-reviewing a terminal status fails.
|
|
26
|
+
- Task intent/plan stay byte-identical before and after a propose→review cycle.
|
package/templates/checkpoint.md
CHANGED
package/templates/decision.md
CHANGED
|
@@ -21,3 +21,9 @@ date: {{date}}
|
|
|
21
21
|
## Recommendation (pilihan yang disarankan + alasan)
|
|
22
22
|
|
|
23
23
|
{{recommendation}}
|
|
24
|
+
|
|
25
|
+
## Terkait (dokumen terkait)
|
|
26
|
+
|
|
27
|
+
- [[../../{{task_id}}/intent]] — maksud kerja
|
|
28
|
+
- [[../../{{task_id}}/plan]] — rencana kerja
|
|
29
|
+
- [[../../index]] — hub memori proyek
|
package/templates/intent.md
CHANGED
|
@@ -21,3 +21,9 @@ project: {{project_id}}
|
|
|
21
21
|
## Open questions
|
|
22
22
|
|
|
23
23
|
{{open_questions}}
|
|
24
|
+
|
|
25
|
+
## Terkait (dokumen terkait)
|
|
26
|
+
|
|
27
|
+
- [[../{{task_id}}/plan]] — rencana kerja untuk intent ini
|
|
28
|
+
- [[../../index]] — hub memori proyek
|
|
29
|
+
- [[../../current-state]] — status terbaru proyek
|
package/templates/plan.md
CHANGED
|
@@ -25,3 +25,10 @@ project: {{project_id}}
|
|
|
25
25
|
## Risks and open questions
|
|
26
26
|
|
|
27
27
|
{{risks}}
|
|
28
|
+
|
|
29
|
+
## Terkait (dokumen terkait)
|
|
30
|
+
|
|
31
|
+
- [[../{{task_id}}/intent]] — maksud dari rencana ini
|
|
32
|
+
- [[../{{task_id}}/history]] — riwayat revisi keputusan
|
|
33
|
+
- [[../../index]] — hub memori proyek
|
|
34
|
+
- [[../../current-state]] — status terbaru proyek
|