@aipper/aiws 0.0.43 → 0.0.45

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.
@@ -0,0 +1,164 @@
1
+ import path from "node:path";
2
+ import fs from "node:fs/promises";
3
+ import { writeMemory, readMemory } from "./store.js";
4
+ import { loadIndex, updateIndex } from "./index.js";
5
+ import { pathExists } from "../fs.js";
6
+ /**
7
+ * Build the list of seedable sources from the workspace root.
8
+ */
9
+ function buildSources(_wsRoot) {
10
+ const sources = [
11
+ {
12
+ uri: "rule://ai-project",
13
+ title: "AI Project Rules",
14
+ tag: "seed:ai-project",
15
+ relPath: "AI_PROJECT.md",
16
+ },
17
+ {
18
+ uri: "project://requirement",
19
+ title: "Requirements",
20
+ tag: "seed:requirement",
21
+ relPath: "REQUIREMENTS.md",
22
+ },
23
+ {
24
+ uri: "project://ai-workspace",
25
+ title: "AI Workspace",
26
+ tag: "seed:ai-workspace",
27
+ relPath: "AI_WORKSPACE.md",
28
+ },
29
+ {
30
+ uri: "rule://agents",
31
+ title: "Agent Rules",
32
+ tag: "seed:agents",
33
+ relPath: "AGENTS.md",
34
+ },
35
+ ];
36
+ return sources;
37
+ }
38
+ /**
39
+ * Format file content as a clean Markdown body for memory storage.
40
+ */
41
+ function formatBody(title, sourcePath, content) {
42
+ return `# ${title}
43
+
44
+ _Source: \`${sourcePath}\`_
45
+
46
+ ${content.trim()}`;
47
+ }
48
+ /**
49
+ * Seed project truth files and artifacts into the memory bank.
50
+ *
51
+ * Scans configured source files in the workspace, reads their content,
52
+ * and writes them as persistent memory entries under a predefined URI scheme.
53
+ *
54
+ * @param wsRoot - Absolute path to the workspace root (must contain .aiws/)
55
+ * @param options.dryRun - If true, only collect URIs without writing
56
+ * @param options.force - If true, overwrite existing memory entries
57
+ * @returns SeedResult with counts of written/skipped entries and list of URIs
58
+ */
59
+ export async function seedMemories(wsRoot, options = {}) {
60
+ const { dryRun = false, force = false } = options;
61
+ const result = { written: 0, skipped: 0, uris: [] };
62
+ // Load existing index for idempotency checks
63
+ const index = await loadIndex(wsRoot);
64
+ // Build dynamic sources: scan .aiws/goals/ and .aiws/plan/
65
+ const sources = buildSources(wsRoot);
66
+ // Add dynamic goals
67
+ const goalsDir = path.join(wsRoot, ".aiws", "goals");
68
+ if (await pathExists(goalsDir)) {
69
+ const goalEntries = await fs.readdir(goalsDir, { withFileTypes: true });
70
+ for (const entry of goalEntries) {
71
+ if (!entry.name.endsWith(".md"))
72
+ continue;
73
+ if (entry.name.startsWith("."))
74
+ continue;
75
+ const baseName = entry.name.replace(/\.md$/, "");
76
+ sources.push({
77
+ uri: `decision://${toUriPath(baseName)}`,
78
+ title: baseName,
79
+ tag: "seed:goal",
80
+ relPath: path.join(".aiws", "goals", entry.name),
81
+ });
82
+ }
83
+ }
84
+ // Add dynamic plans
85
+ const planDir = path.join(wsRoot, ".aiws", "plan");
86
+ if (await pathExists(planDir)) {
87
+ const planEntries = await fs.readdir(planDir, { withFileTypes: true });
88
+ for (const entry of planEntries) {
89
+ if (!entry.name.endsWith(".md"))
90
+ continue;
91
+ if (entry.name.startsWith("."))
92
+ continue;
93
+ const baseName = entry.name.replace(/\.md$/, "");
94
+ sources.push({
95
+ uri: `change://${toUriPath(baseName)}`,
96
+ title: baseName,
97
+ tag: "seed:plan",
98
+ relPath: path.join(".aiws", "plan", entry.name),
99
+ });
100
+ }
101
+ }
102
+ for (const source of sources) {
103
+ const absPath = path.join(wsRoot, source.relPath);
104
+ // Skip if the source file doesn't exist
105
+ if (!(await pathExists(absPath)))
106
+ continue;
107
+ // Idempotency: skip if URI already exists and not force
108
+ if (!force && index.memories[source.uri]) {
109
+ result.skipped++;
110
+ result.uris.push(source.uri);
111
+ continue;
112
+ }
113
+ if (dryRun) {
114
+ result.uris.push(source.uri);
115
+ continue;
116
+ }
117
+ // Read file content and format body
118
+ const content = await fs.readFile(absPath, "utf8");
119
+ // For truth files, extract a meaningful title from the first heading
120
+ const title = extractTitle(content) ?? source.title;
121
+ const body = formatBody(title, source.relPath, content);
122
+ // Write memory entry
123
+ await writeMemory(wsRoot, source.uri, body, {
124
+ title,
125
+ tags: [source.tag],
126
+ });
127
+ // Update index so it reflects immediately
128
+ const entry = await readMemory(wsRoot, source.uri);
129
+ await updateIndex(wsRoot, source.uri, {
130
+ title: entry.title,
131
+ domain: entry.domain,
132
+ path: entry.path,
133
+ created: entry.created,
134
+ updated: entry.updated,
135
+ tags: entry.tags,
136
+ disclosure: entry.disclosure,
137
+ });
138
+ result.written++;
139
+ result.uris.push(source.uri);
140
+ }
141
+ return result;
142
+ }
143
+ /**
144
+ * Try to extract the first Markdown heading from content.
145
+ */
146
+ function extractTitle(content) {
147
+ const match = content.match(/^#\s+(.+)$/m);
148
+ return match?.[1]?.trim() ?? null;
149
+ }
150
+ /**
151
+ * Sanitize a filename to a valid URI path segment.
152
+ * URI path must match: [a-z0-9]+(-[a-z0-9]+)*
153
+ */
154
+ function toUriPath(name) {
155
+ const cleaned = name
156
+ .toLowerCase()
157
+ .replace(/_/g, "-")
158
+ .replace(/\./g, "-")
159
+ .replace(/[^a-z0-9-]/g, "")
160
+ .replace(/-+/g, "-")
161
+ .replace(/^-|-$/g, "");
162
+ return cleaned || "untitled";
163
+ }
164
+ //# sourceMappingURL=seed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed.js","sourceRoot":"","sources":["../../src/memory-bank/seed.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { MemoryEntry, WriteOptions } from "./types.js";
2
+ /**
3
+ * Return the absolute path to the memory-bank directory.
4
+ */
5
+ export declare function getMemoryBankDir(wsRoot: string): string;
6
+ /**
7
+ * Read a memory entry from disk.
8
+ * Supports both new files with YAML frontmatter and legacy plain MD files.
9
+ * Tries the standard path (domain/path.md) first, then falls back to flat path (path.md)
10
+ * for backward compatibility with existing memory-bank files at the root level.
11
+ */
12
+ export declare function readMemory(wsRoot: string, uri: string): Promise<MemoryEntry>;
13
+ /**
14
+ * Write a memory entry to disk with YAML frontmatter.
15
+ */
16
+ export declare function writeMemory(wsRoot: string, uri: string, body: string, options?: WriteOptions): Promise<void>;
17
+ /**
18
+ * Delete a memory file from disk.
19
+ */
20
+ export declare function deleteMemory(wsRoot: string, uri: string): Promise<void>;
21
+ /**
22
+ * Collect all .md files under memory-bank/, returning relative paths from memory-bank/.
23
+ */
24
+ export declare function collectMemoryFiles(wsRoot: string): Promise<string[]>;
@@ -0,0 +1,193 @@
1
+ import path from "node:path";
2
+ import fs from "node:fs/promises";
3
+ import yaml from "js-yaml";
4
+ import { parseUri, uriToRelPath } from "./uri.js";
5
+ import { pathExists, ensureDir } from "../fs.js";
6
+ /**
7
+ * Return the absolute path to the memory-bank directory.
8
+ */
9
+ export function getMemoryBankDir(wsRoot) {
10
+ return path.join(wsRoot, ".aiws", "memory-bank");
11
+ }
12
+ /**
13
+ * Parse frontmatter (YAML between --- delimiters) from markdown content.
14
+ * Returns { frontmatter, body }. If no frontmatter found, frontmatter is {} and body is the full content.
15
+ */
16
+ function parseFrontmatter(content) {
17
+ const trimmed = content.trimStart();
18
+ if (trimmed.startsWith("---")) {
19
+ const endIdx = trimmed.indexOf("---", 3);
20
+ if (endIdx !== -1) {
21
+ const yamlBlock = trimmed.slice(3, endIdx).trim();
22
+ const body = trimmed.slice(endIdx + 3).trim();
23
+ try {
24
+ const parsed = yaml.load(yamlBlock);
25
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
26
+ return { frontmatter: parsed, body };
27
+ }
28
+ }
29
+ catch {
30
+ // If YAML parsing fails, treat as no frontmatter
31
+ }
32
+ }
33
+ }
34
+ return { frontmatter: {}, body: trimmed };
35
+ }
36
+ /**
37
+ * Format frontmatter + body into a markdown string.
38
+ */
39
+ function formatWithFrontmatter(frontmatter, body) {
40
+ const yamlStr = yaml.dump(frontmatter, { lineWidth: 120, noRefs: true });
41
+ return `---\n${yamlStr}---\n${body}\n`;
42
+ }
43
+ /**
44
+ * Extract a title from a memory file path or body.
45
+ */
46
+ function inferTitle(relPath, body) {
47
+ // Try first H1 heading
48
+ const h1Match = body.match(/^#\s+(.+)$/m);
49
+ if (h1Match?.[1])
50
+ return h1Match[1].trim();
51
+ // Fall back to filename without extension
52
+ const basename = path.basename(relPath, ".md");
53
+ // Convert kebab-case to Title Case
54
+ return basename
55
+ .split("-")
56
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
57
+ .join(" ");
58
+ }
59
+ /**
60
+ * Infer domain from a relative path under memory-bank/.
61
+ * Domain is the first path segment, fallback to "general".
62
+ */
63
+ function inferDomain(relPath) {
64
+ const parts = relPath.replaceAll(path.sep, "/").split("/");
65
+ return parts.length > 1 ? parts[0] ?? "general" : "general";
66
+ }
67
+ /**
68
+ * Read a memory entry from disk.
69
+ * Supports both new files with YAML frontmatter and legacy plain MD files.
70
+ * Tries the standard path (domain/path.md) first, then falls back to flat path (path.md)
71
+ * for backward compatibility with existing memory-bank files at the root level.
72
+ */
73
+ export async function readMemory(wsRoot, uri) {
74
+ const { domain, path: uriPath } = parseUri(uri);
75
+ const memDir = getMemoryBankDir(wsRoot);
76
+ const standardRelPath = uriToRelPath(domain, uriPath);
77
+ const standardAbsPath = path.join(memDir, standardRelPath);
78
+ // Try standard path first, fall back to flat file for legacy compatibility
79
+ let absPath;
80
+ let relPath;
81
+ if (await pathExists(standardAbsPath)) {
82
+ absPath = standardAbsPath;
83
+ relPath = standardRelPath;
84
+ }
85
+ else {
86
+ const flatRelPath = `${uriPath}.md`;
87
+ const flatAbsPath = path.join(memDir, flatRelPath);
88
+ if (await pathExists(flatAbsPath)) {
89
+ absPath = flatAbsPath;
90
+ relPath = flatRelPath;
91
+ }
92
+ else {
93
+ throw new Error(`Memory not found: ${uri} (tried ${standardAbsPath} and ${flatAbsPath})`);
94
+ }
95
+ }
96
+ const content = await fs.readFile(absPath, "utf8");
97
+ const { frontmatter, body } = parseFrontmatter(content);
98
+ // Support legacy files without frontmatter
99
+ const title = frontmatter.title ?? inferTitle(relPath, body);
100
+ const created = frontmatter.created ?? new Date().toISOString();
101
+ const updated = frontmatter.updated ?? new Date().toISOString();
102
+ const disclosure = frontmatter.disclosure;
103
+ const rawTags = frontmatter.tags;
104
+ const tags = Array.isArray(rawTags) ? rawTags.map(String) : [];
105
+ const inferredDomain = inferDomain(relPath);
106
+ return {
107
+ uri,
108
+ title,
109
+ domain: inferredDomain,
110
+ path: relPath,
111
+ created,
112
+ updated,
113
+ disclosure,
114
+ tags,
115
+ body,
116
+ frontmatter,
117
+ };
118
+ }
119
+ /**
120
+ * Write a memory entry to disk with YAML frontmatter.
121
+ */
122
+ export async function writeMemory(wsRoot, uri, body, options) {
123
+ const { domain, path: uriPath } = parseUri(uri);
124
+ const relPath = uriToRelPath(domain, uriPath);
125
+ const memDir = getMemoryBankDir(wsRoot);
126
+ const absPath = path.join(memDir, relPath);
127
+ let created = new Date().toISOString();
128
+ const existing = await pathExists(absPath);
129
+ if (existing) {
130
+ try {
131
+ const prev = await readMemory(wsRoot, uri);
132
+ created = prev.created;
133
+ }
134
+ catch {
135
+ // Use current time if we can't read existing
136
+ }
137
+ }
138
+ const frontmatter = {
139
+ title: options?.title ?? inferTitle(relPath, body),
140
+ created,
141
+ updated: new Date().toISOString(),
142
+ };
143
+ if (options?.disclosure) {
144
+ frontmatter.disclosure = options.disclosure;
145
+ }
146
+ if (options?.tags && options.tags.length > 0) {
147
+ frontmatter.tags = options.tags;
148
+ }
149
+ const content = formatWithFrontmatter(frontmatter, body.trim());
150
+ await ensureDir(path.dirname(absPath));
151
+ await fs.writeFile(absPath, content, "utf8");
152
+ }
153
+ /**
154
+ * Delete a memory file from disk.
155
+ */
156
+ export async function deleteMemory(wsRoot, uri) {
157
+ const { domain, path: uriPath } = parseUri(uri);
158
+ const relPath = uriToRelPath(domain, uriPath);
159
+ const absPath = path.join(getMemoryBankDir(wsRoot), relPath);
160
+ if (await pathExists(absPath)) {
161
+ await fs.unlink(absPath);
162
+ }
163
+ }
164
+ /**
165
+ * Collect all .md files under memory-bank/, returning relative paths from memory-bank/.
166
+ */
167
+ export async function collectMemoryFiles(wsRoot) {
168
+ const memDir = getMemoryBankDir(wsRoot);
169
+ if (!(await pathExists(memDir)))
170
+ return [];
171
+ const results = [];
172
+ const stack = [""];
173
+ while (stack.length > 0) {
174
+ const rel = stack.pop();
175
+ const abs = path.join(memDir, rel);
176
+ const entries = await fs.readdir(abs, { withFileTypes: true });
177
+ for (const entry of entries) {
178
+ if (entry.name.startsWith("."))
179
+ continue; // skip dotfiles like .index.yaml
180
+ const entryRel = rel ? `${rel}/${entry.name}` : entry.name;
181
+ const entryAbs = path.join(memDir, entryRel);
182
+ if (entry.isDirectory()) {
183
+ stack.push(entryRel);
184
+ }
185
+ else if (entry.isFile() && entry.name.endsWith(".md")) {
186
+ results.push(entryRel);
187
+ }
188
+ }
189
+ }
190
+ results.sort();
191
+ return results;
192
+ }
193
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/memory-bank/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ export interface MemoryEntry {
2
+ uri: string;
3
+ title: string;
4
+ domain: string;
5
+ path: string;
6
+ created: string;
7
+ updated: string;
8
+ disclosure?: string;
9
+ tags: string[];
10
+ body: string;
11
+ frontmatter: Record<string, unknown>;
12
+ }
13
+ export interface IndexData {
14
+ memories: Record<string, IndexEntry>;
15
+ }
16
+ export interface IndexEntry {
17
+ title: string;
18
+ domain: string;
19
+ path: string;
20
+ created: string;
21
+ updated: string;
22
+ tags: string[];
23
+ disclosure?: string;
24
+ }
25
+ export interface Link {
26
+ from: string;
27
+ to: string;
28
+ created: string;
29
+ }
30
+ export interface SearchResult {
31
+ uri: string;
32
+ title: string;
33
+ snippet: string;
34
+ }
35
+ export interface WriteOptions {
36
+ title?: string;
37
+ tags?: string[];
38
+ disclosure?: string;
39
+ }
40
+ export interface RelatedEntry {
41
+ uri: string;
42
+ title: string;
43
+ disclosure: string;
44
+ snippet: string;
45
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/memory-bank/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Split `domain://path` into domain and path parts.
3
+ * Throws UserError if the format is invalid.
4
+ */
5
+ export declare function parseUri(uri: string): {
6
+ domain: string;
7
+ path: string;
8
+ };
9
+ /**
10
+ * Convert domain and path to a relative file path under memory-bank/.
11
+ */
12
+ export declare function uriToRelPath(domain: string, path: string): string;
13
+ /**
14
+ * Validate a memory URI format without throwing.
15
+ */
16
+ export declare function validateUri(uri: string): boolean;
@@ -0,0 +1,52 @@
1
+ import { UserError } from "../errors.js";
2
+ const SEGMENT_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
3
+ /**
4
+ * Split `domain://path` into domain and path parts.
5
+ * Throws UserError if the format is invalid.
6
+ */
7
+ export function parseUri(uri) {
8
+ const sep = "://";
9
+ const idx = uri.indexOf(sep);
10
+ if (idx === -1) {
11
+ throw new UserError(`Invalid memory URI format: ${uri}`, {
12
+ details: "Expected format: domain://path (e.g. core://architecture)",
13
+ });
14
+ }
15
+ const domain = uri.slice(0, idx);
16
+ const path = uri.slice(idx + sep.length);
17
+ if (!domain || !path) {
18
+ throw new UserError(`Invalid memory URI: domain and path must not be empty`, {
19
+ details: `Parsed domain="${domain}" path="${path}" from "${uri}"`,
20
+ });
21
+ }
22
+ if (!SEGMENT_RE.test(domain)) {
23
+ throw new UserError(`Invalid domain in memory URI: "${domain}"`, {
24
+ details: "Domain must match: [a-z0-9]+(-[a-z0-9]+)*",
25
+ });
26
+ }
27
+ if (!SEGMENT_RE.test(path)) {
28
+ throw new UserError(`Invalid path in memory URI: "${path}"`, {
29
+ details: "Path must match: [a-z0-9]+(-[a-z0-9]+)*",
30
+ });
31
+ }
32
+ return { domain, path };
33
+ }
34
+ /**
35
+ * Convert domain and path to a relative file path under memory-bank/.
36
+ */
37
+ export function uriToRelPath(domain, path) {
38
+ return `${domain}/${path}.md`;
39
+ }
40
+ /**
41
+ * Validate a memory URI format without throwing.
42
+ */
43
+ export function validateUri(uri) {
44
+ try {
45
+ parseUri(uri);
46
+ return true;
47
+ }
48
+ catch {
49
+ return false;
50
+ }
51
+ }
52
+ //# sourceMappingURL=uri.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uri.js","sourceRoot":"","sources":["../../src/memory-bank/uri.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,UAAU,GAAG,0BAA0B,CAAC;AAE9C;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,MAAM,GAAG,GAAG,KAAK,CAAC;IAClB,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,SAAS,CAAC,8BAA8B,GAAG,EAAE,EAAE;YACvD,OAAO,EAAE,2DAA2D;SACrE,CAAC,CAAC;IACL,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,SAAS,CAAC,uDAAuD,EAAE;YAC3E,OAAO,EAAE,kBAAkB,MAAM,WAAW,IAAI,WAAW,GAAG,GAAG;SAClE,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,SAAS,CAAC,kCAAkC,MAAM,GAAG,EAAE;YAC/D,OAAO,EAAE,2CAA2C;SACrD,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,SAAS,CAAC,gCAAgC,IAAI,GAAG,EAAE;YAC3D,OAAO,EAAE,yCAAyC;SACnD,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,IAAY;IACvD,OAAO,GAAG,MAAM,IAAI,IAAI,KAAK,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,CAAC;QACH,QAAQ,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -2,3 +2,4 @@ export interface ResolveWorkspaceRootOptions {
2
2
  create?: boolean;
3
3
  }
4
4
  export declare function resolveWorkspaceRoot(targetPath: string, options?: ResolveWorkspaceRootOptions): Promise<string>;
5
+ export declare function getWorkspaceRoot(): Promise<string>;
package/dist/workspace.js CHANGED
@@ -16,4 +16,17 @@ export async function resolveWorkspaceRoot(targetPath, options) {
16
16
  }
17
17
  throw new UserError(`Path does not exist: ${abs}`);
18
18
  }
19
+ export async function getWorkspaceRoot() {
20
+ let dir = process.cwd();
21
+ while (true) {
22
+ if (await pathExists(path.join(dir, ".aiws")))
23
+ return dir;
24
+ if (await pathExists(path.join(dir, "package.json")))
25
+ return dir;
26
+ const parent = path.dirname(dir);
27
+ if (parent === dir)
28
+ throw new UserError("Cannot find workspace root (no .aiws/ or package.json found)");
29
+ dir = parent;
30
+ }
31
+ }
19
32
  //# sourceMappingURL=workspace.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAMxC,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,UAAkB,EAClB,OAAqC;IAErC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,IAAI,GAAG,CAAC,CAAC;IAC3D,IAAI,MAAM,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE;YAAE,MAAM,IAAI,SAAS,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAC;QACtE,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,OAAO,GAAG,CAAC;IACb,CAAC;IACD,MAAM,IAAI,SAAS,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAMxC,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,UAAkB,EAClB,OAAqC;IAErC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,IAAI,GAAG,CAAC,CAAC;IAC3D,IAAI,MAAM,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE;YAAE,MAAM,IAAI,SAAS,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAC;QACtE,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,OAAO,GAAG,CAAC;IACb,CAAC;IACD,MAAM,IAAI,SAAS,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACxB,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QAC1D,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QACjE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM,IAAI,SAAS,CAAC,8DAA8D,CAAC,CAAC;QACxG,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@aipper/aiws",
3
- "version": "0.0.43",
3
+ "version": "0.0.45",
4
4
  "description": "AI Workspace CLI (init/update/validate) for Claude Code / OpenCode / Codex.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "aiws": "./bin/aiws.js"
8
8
  },
9
9
  "dependencies": {
10
- "@aipper/aiws-spec": "0.0.43"
10
+ "@aipper/aiws-spec": "0.0.45",
11
+ "js-yaml": "^4.1.0"
11
12
  },
12
13
  "files": [
13
14
  "bin",
@@ -26,6 +27,7 @@
26
27
  "access": "public"
27
28
  },
28
29
  "devDependencies": {
30
+ "@types/js-yaml": "^4.0.9",
29
31
  "@types/node": "^25.9.0",
30
32
  "typescript": "^6.0.3",
31
33
  "vitest": "^3.0.0"