@aipper/aiws-spec 0.0.51 → 0.0.52

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.
@@ -14,13 +14,13 @@
14
14
  ],
15
15
  "recommended_a": [
16
16
  {
17
- "id": "pi-extension-settings",
18
- "package": "pi-extension-settings",
17
+ "id": "@juanibiapina/pi-extension-settings",
18
+ "package": "@juanibiapina/pi-extension-settings",
19
19
  "tier": "recommended_a"
20
20
  },
21
21
  {
22
- "id": "pi-powerbar",
23
- "package": "pi-powerbar",
22
+ "id": "@juanibiapina/pi-powerbar",
23
+ "package": "@juanibiapina/pi-powerbar",
24
24
  "tier": "recommended_a"
25
25
  },
26
26
  {
@@ -39,8 +39,8 @@
39
39
  "tier": "recommended_a"
40
40
  },
41
41
  {
42
- "id": "rpiv-ask-user-question",
43
- "package": "rpiv-ask-user-question",
42
+ "id": "@juicesharp/rpiv-ask-user-question",
43
+ "package": "@juicesharp/rpiv-ask-user-question",
44
44
  "tier": "recommended_a"
45
45
  },
46
46
  {
@@ -63,7 +63,8 @@
63
63
  {
64
64
  "id": "pi-mcp-adapter",
65
65
  "package": "pi-mcp-adapter",
66
- "tier": "recommended_b"
66
+ "tier": "recommended_b",
67
+ "reason": "MCP adapter; heavy deps \u2014 sequential install with timeout; may need manual retry"
67
68
  },
68
69
  {
69
70
  "id": "pi-fff",
@@ -76,8 +77,8 @@
76
77
  "tier": "recommended_b"
77
78
  },
78
79
  {
79
- "id": "plan-mode",
80
- "package": "plan-mode",
80
+ "id": "pi-plan-mode",
81
+ "package": "pi-plan-mode",
81
82
  "tier": "recommended_b"
82
83
  },
83
84
  {
@@ -54,12 +54,12 @@ Low conflict with AIWS governance; useful quality-of-life.
54
54
 
55
55
  | package | notes |
56
56
  |---------|--------|
57
- | `pi-extension-settings` | settings UX |
58
- | `pi-powerbar` | status bar |
57
+ | `@juanibiapina/pi-extension-settings` | settings UX |
58
+ | `@juanibiapina/pi-powerbar` | status bar |
59
59
  | `pi-lsp` | LSP |
60
60
  | `pi-hashline-edit-pro` | edit helper (watch tool names vs force deny) |
61
61
  | `rpiv-todo` | todos |
62
- | `rpiv-ask-user-question` | structured questions |
62
+ | `@juicesharp/rpiv-ask-user-question` | structured questions |
63
63
  | `pi-btw` | asides |
64
64
  | `pi-caffeinate` | keep awake |
65
65
  | `pi-workspace-history` | history |
@@ -68,10 +68,10 @@ Low conflict with AIWS governance; useful quality-of-life.
68
68
 
69
69
  | package | notes |
70
70
  |---------|--------|
71
- | `pi-mcp-adapter` | MCP |
71
+ | `pi-mcp-adapter` | MCP (heavy deps; install may hang — retry alone or skip) |
72
72
  | `pi-fff` | file finder |
73
73
  | `pi-slopchop` | slop cleanup |
74
- | `plan-mode` | plan UX (AIWS keeps plan truth) |
74
+ | `pi-plan-mode` | plan UX (AIWS keeps plan truth) |
75
75
  | `pi-cache-optimizer` | cache (truncation caution) |
76
76
  | `pi-rtk-optimizer` | RTK |
77
77
  | `pi-agent-browser-native` | browser |
@@ -102,7 +102,7 @@ Low conflict with AIWS governance; useful quality-of-life.
102
102
  - Missing **required** → exit code ≠ 0
103
103
  - Conflicts / forbidden installed → warn (exit ≠ 0 if any required missing or any conflict)
104
104
  - `init --pi` / `update` (when `.pi/` exists or `--pi`): print same report as **warn**; do not fail init/update by default
105
- - Optional `--install-pi-plugins`: install **required only** (user scope); recommended stay print-only
105
+ - Optional `--install-pi-plugins`: install **all declared installable** plugins (required + recommended A/B, user scope); never forbidden; default without flag remains detect+prompt only
106
106
 
107
107
  ## Related
108
108
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aipper/aiws-spec",
3
- "version": "0.0.51",
3
+ "version": "0.0.52",
4
4
  "description": "AIWS spec and templates (single source of truth).",
5
5
  "type": "module",
6
6
  "files": [
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Memory Autoload Plugin
3
+ *
4
+ * Injects AIWS memory context at session start so each session
5
+ * has continuity without needing the nocturne_memory MCP server.
6
+ *
7
+ * What it does:
8
+ * 1. On the first user message of a new session, reads:
9
+ * - Active goal(s) from .aiws/goals/*.state.json
10
+ * - Recent decisions from .aiws/memory-bank/decision/ (last 3)
11
+ * - Project overview from .aiws/memory-bank/project/
12
+ * 2. Injects a <memory-context> block into the assistant's first response.
13
+ * 3. Deduplicates per session — injects once only.
14
+ *
15
+ * Disable: export MEMORY_AUTOLOAD_DISABLE=1
16
+ *
17
+ * @module memory-autoload
18
+ */
19
+
20
+ import { readFileSync, existsSync, readdirSync } from "node:fs";
21
+ import { join } from "node:path";
22
+
23
+ const MEMORY_BANK = ".aiws/memory-bank";
24
+ const GOALS_DIR = ".aiws/goals";
25
+
26
+ export const MemoryAutoloadPlugin = async ({ project, client, directory }) => {
27
+ const processed = new Set();
28
+
29
+ return {
30
+ "chat.message": async (input, output) => {
31
+ const sid = input?.sessionID;
32
+ if (!sid || processed.has(sid)) return;
33
+ if (process.env.MEMORY_AUTOLOAD_DISABLE === "1") {
34
+ processed.add(sid);
35
+ return;
36
+ }
37
+
38
+ const root = directory || process.cwd();
39
+ const bankDir = join(root, MEMORY_BANK);
40
+ if (!existsSync(bankDir)) {
41
+ processed.add(sid);
42
+ return;
43
+ }
44
+
45
+ const blocks = [];
46
+
47
+ // ── 1. Active/paused goals (ADVISORY ONLY — not FSM authority) ─
48
+ // TOOLING-003D: authoritative goal-context + next_action come from
49
+ // session-start → buildSessionContext → getActiveGoal(s).
50
+ // memory-autoload must NOT become authority over goal state.
51
+ try {
52
+ const goalsDir = join(root, GOALS_DIR);
53
+ if (existsSync(goalsDir)) {
54
+ const files = readdirSync(goalsDir).filter((f) =>
55
+ f.endsWith(".state.json"),
56
+ );
57
+ const advisory = [];
58
+ for (const file of files.sort()) {
59
+ try {
60
+ const state = JSON.parse(
61
+ readFileSync(join(goalsDir, file), "utf-8"),
62
+ );
63
+ const st = state.status;
64
+ if (st === "active" || st === "paused") {
65
+ const phase = state.current_phase ?? "?";
66
+ const iter = state.iteration ?? "?";
67
+ advisory.push(
68
+ `- [${st}] ${state.goal_id || file} — phase=${phase}, iteration=${iter}`,
69
+ );
70
+ }
71
+ } catch {
72
+ /* skip malformed state file */
73
+ }
74
+ }
75
+ if (advisory.length) {
76
+ blocks.push(
77
+ "[Goals — advisory memory only; use session <goal-context> for next_action]",
78
+ );
79
+ blocks.push(...advisory);
80
+ }
81
+ }
82
+ } catch {
83
+ /* goals dir missing */
84
+ }
85
+
86
+ // ── 2. Recent decisions (last 3, sorted by filename) ──────────
87
+ try {
88
+ const decDir = join(bankDir, "decision");
89
+ if (existsSync(decDir)) {
90
+ const files = readdirSync(decDir)
91
+ .filter((f) => f.endsWith(".md") && f !== "handoff-evidence.md")
92
+ .sort()
93
+ .reverse()
94
+ .slice(0, 3);
95
+ for (const file of files) {
96
+ try {
97
+ const content = readFileSync(join(decDir, file), "utf-8");
98
+ const title =
99
+ content
100
+ .split("\n")
101
+ .find((l) => l.startsWith("#"))
102
+ ?.replace(/^#+\s*/, "") || file.replace(".md", "");
103
+ const summary = content
104
+ .split("\n")
105
+ .slice(1, 8)
106
+ .filter((l) => l.trim())
107
+ .join("\n")
108
+ .trim();
109
+ blocks.push(`\n[Decision] ${title}\n${summary}`);
110
+ } catch {
111
+ /* skip unreadable file */
112
+ }
113
+ }
114
+ }
115
+ } catch {
116
+ /* decision dir missing */
117
+ }
118
+
119
+ // ── 3. Project overview ────────────────────────────────────────
120
+ try {
121
+ const projDir = join(bankDir, "project");
122
+ if (existsSync(projDir)) {
123
+ const files = readdirSync(projDir).filter((f) => f.endsWith(".md"));
124
+ for (const file of files.slice(0, 2)) {
125
+ try {
126
+ const content = readFileSync(join(projDir, file), "utf-8");
127
+ const title =
128
+ content
129
+ .split("\n")
130
+ .find((l) => l.startsWith("#"))
131
+ ?.replace(/^#+\s*/, "") || file.replace(".md", "");
132
+ const excerpt = content
133
+ .split("\n")
134
+ .slice(1, 12)
135
+ .filter((l) => l.trim())
136
+ .join("\n")
137
+ .trim();
138
+ blocks.push(`\n[Project: ${title}]\n${excerpt}`);
139
+ } catch {
140
+ /* skip */
141
+ }
142
+ }
143
+ }
144
+ } catch {
145
+ /* project dir missing */
146
+ }
147
+
148
+ // ── 4. If aiws memory boot produces anything, append it ────────
149
+ // (skipped — avoids shell dependency; use --disclosure boot on
150
+ // `aiws memory write` and the injected goal/decision blocks
151
+ // above already provide sufficient context)
152
+
153
+ if (blocks.length === 0) {
154
+ processed.add(sid);
155
+ return;
156
+ }
157
+
158
+ const context = `<memory-context>\n${blocks.join("\n")}\n</memory-context>`;
159
+
160
+ const parts = output?.parts || [];
161
+ const textIdx = parts.findIndex(
162
+ (p) => p.type === "text" && p.text !== undefined,
163
+ );
164
+ if (textIdx !== -1) {
165
+ parts[textIdx].text = `${context}\n\n${parts[textIdx].text}`;
166
+ } else {
167
+ parts.unshift({ type: "text", text: context });
168
+ }
169
+
170
+ try {
171
+ await client.app.log({
172
+ body: {
173
+ service: "memory-autoload",
174
+ level: "info",
175
+ message: `Injected ${blocks.length} memory blocks for session ${sid.slice(0, 12)}`,
176
+ },
177
+ });
178
+ } catch {
179
+ /* logging optional */
180
+ }
181
+
182
+ processed.add(sid);
183
+ },
184
+ };
185
+ };
@@ -32,3 +32,16 @@ Red Flags(这些想法都是错的):
32
32
  <!-- AIWS_MANAGED_END:agents -->
33
33
 
34
34
  你可以在本段下方追加项目自定义说明;`aiws update` 不会改动托管块以外内容。
35
+
36
+ ## Memory Protocol
37
+
38
+ 本仓库使用 `aiws memory` 系统持久化跨会话知识。automation 协议:
39
+
40
+ 1. **自动注入(插件)** — `.opencode/plugins/memory-autoload.js` 在会话首次消息时读取活跃目标、近期决策、项目概览并注入 `<memory-context>`。需依赖:`MEMORY_AUTOLOAD_DISABLE=1` 可关闭
41
+ 2. **会话启动时** — 自动读取 `.aiws/memory-bank/.index.yaml` 获取记忆索引,了解已记录的知识领域
42
+ 3. **回答前** — 若问题涉及已记忆的领域,先用 `aiws memory search <keywords>` 检索相关记录
43
+ 4. **获取新知识后** — 对重要决策、根因分析、架构约定等跨会话有价值的信息,使用 `aiws memory write <domain>://<path>` 写入永久记忆(写入会自动更新索引)。标记 `--disclosure boot` 可让记忆出现在下次插件注入中
44
+ 5. **记忆关联** — 对相关记忆使用 `aiws memory link add` 建立关系
45
+ 6. **nocturne_memory MCP** — 仓库预配了远程 MCP 服务器(nocturne_memory),作为全局知识层自动可用,两者互补而非替代。当前未集成到 OpenCode 配置中
46
+
47
+ 目标:把关键认知固化到 git-tracked 文件,实现跨机器/跨会话的知识连续性。
@@ -64,6 +64,7 @@
64
64
  ".opencode/plugins/aiws-inject-context.js",
65
65
  ".opencode/plugins/aiws-session-start.js",
66
66
  ".opencode/plugins/aiws-workflow-state.js",
67
+ ".opencode/plugins/memory-autoload.js",
67
68
  ".opencode/lib/aiws-context.js",
68
69
  ".opencode/commands/**",
69
70
  ".opencode/skills/**",
@@ -257,6 +258,7 @@
257
258
  ".opencode/plugins/aiws-inject-context.js",
258
259
  ".opencode/plugins/aiws-session-start.js",
259
260
  ".opencode/plugins/aiws-workflow-state.js",
261
+ ".opencode/plugins/memory-autoload.js",
260
262
  ".opencode/lib/aiws-context.js",
261
263
  ".opencode/command/p-aiws-change-archive.md",
262
264
  ".opencode/command/p-aiws-change-finish.md",