@erclx/aitk 0.36.0 → 0.38.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/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/claude-design-extract/REQUIREMENT.md +42 -0
- package/claude/skills/claude-diagram/REQUIREMENT.md +45 -0
- package/claude/skills/claude-groundwork/REQUIREMENT.md +44 -0
- package/claude/skills/claude-memory-capture/REQUIREMENT.md +40 -0
- package/claude/skills/claude-orchestrate/REQUIREMENT.md +44 -0
- package/claude/skills/claude-roadmap/REQUIREMENT.md +41 -0
- package/claude/skills/claude-screencast/REQUIREMENT.md +39 -0
- package/claude/skills/claude-slides-draft/REQUIREMENT.md +39 -0
- package/claude/skills/claude-tasks/REQUIREMENT.md +43 -0
- package/claude/skills/claude-ui-test/REQUIREMENT.md +40 -0
- package/claude/skills/claude-ux-audit/REQUIREMENT.md +39 -0
- package/claude/skills/claude-worktree/REQUIREMENT.md +41 -0
- package/claude/skills/cli-script/REQUIREMENT.md +40 -0
- package/claude/skills/create-rule/REQUIREMENT.md +42 -0
- package/docs/agents.md +21 -8
- package/docs/operating-model.md +1 -1
- package/docs/visual-design-workflow.md +1 -1
- package/package.json +1 -1
- package/src/commands/context.ts +129 -14
- package/src/context/audit.ts +119 -0
- package/src/context/folders.ts +95 -12
- package/tooling/base/seeds/.claude/context/ci.md +7 -1
- package/tooling/base/seeds/.claude/context/development.md +8 -1
- package/tooling/base/seeds/.claude/context/index.md +11 -0
- package/tooling/claude/seeds/.claude/context/index.md +0 -8
package/src/context/folders.ts
CHANGED
|
@@ -17,6 +17,12 @@ export const DEFAULT_FOLDERS: readonly string[] = [
|
|
|
17
17
|
'wireframes',
|
|
18
18
|
]
|
|
19
19
|
|
|
20
|
+
/** The base every folder in the default list sits under. */
|
|
21
|
+
const CLAUDE_BASE = '.claude'
|
|
22
|
+
|
|
23
|
+
/** The project root, reached only by a name the caller asked for. */
|
|
24
|
+
const ROOT_BASE = '.'
|
|
25
|
+
|
|
20
26
|
export interface AuditedFolder {
|
|
21
27
|
/**
|
|
22
28
|
* The requested folder name this was resolved under, which is what says
|
|
@@ -25,24 +31,51 @@ export interface AuditedFolder {
|
|
|
25
31
|
* `.claude/context/claude-plugin` is governed as `context`.
|
|
26
32
|
*/
|
|
27
33
|
readonly name: string
|
|
34
|
+
/**
|
|
35
|
+
* The base the name resolved under, which is what says whether the folder is
|
|
36
|
+
* in the citation check's scope.
|
|
37
|
+
*/
|
|
38
|
+
readonly base: string
|
|
28
39
|
/** Repo-relative folder path, used verbatim in every report line. */
|
|
29
40
|
readonly rel: string
|
|
30
41
|
readonly indexPath: string
|
|
31
42
|
/** Absolute paths of the folder's own entries, excluding its `index.md`. */
|
|
32
43
|
readonly entries: readonly string[]
|
|
44
|
+
/**
|
|
45
|
+
* Whether this is a sub-area a domain split into rather than the folder
|
|
46
|
+
* named under `.claude/`.
|
|
47
|
+
*
|
|
48
|
+
* The entries of a split folder describe one domain between them, so a rule
|
|
49
|
+
* about what a domain declares is answered by the folder. The entries of the
|
|
50
|
+
* named folder are one domain each, and a rule answered by a sibling there
|
|
51
|
+
* would let one entry stand in for domains it says nothing about.
|
|
52
|
+
*/
|
|
53
|
+
readonly nested: boolean
|
|
33
54
|
}
|
|
34
55
|
|
|
35
56
|
/**
|
|
36
|
-
* Names the requested folders that actually exist, which is the
|
|
37
|
-
* check's scope.
|
|
57
|
+
* Names the requested `.claude/` folders that actually exist, which is the
|
|
58
|
+
* citation check's scope.
|
|
38
59
|
*
|
|
39
60
|
* A skill or seed pointing into `.claude/wireframes/` is a live instruction for
|
|
40
61
|
* a project that carries the folder and says nothing about one that does not.
|
|
41
62
|
* Checking a path into an absent folder would fail eight shipped references
|
|
42
63
|
* here for the sole reason that this repository has no wireframes.
|
|
64
|
+
*
|
|
65
|
+
* A folder resolved at the project root is measured and stays out of this. The
|
|
66
|
+
* pattern the citation check builds spells the `.claude/` prefix, so admitting
|
|
67
|
+
* a root name there would check `.claude/<name>/` paths the audit never read.
|
|
68
|
+
* Widening the pattern to the root spelling is a separate change, since a bare
|
|
69
|
+
* `docs/x.md` appears in prose that references nothing.
|
|
43
70
|
*/
|
|
44
71
|
export function presentNames(folders: readonly AuditedFolder[]): string[] {
|
|
45
|
-
return [
|
|
72
|
+
return [
|
|
73
|
+
...new Set(
|
|
74
|
+
folders
|
|
75
|
+
.filter((folder) => folder.base === CLAUDE_BASE)
|
|
76
|
+
.map((folder) => folder.name),
|
|
77
|
+
),
|
|
78
|
+
]
|
|
46
79
|
}
|
|
47
80
|
|
|
48
81
|
async function readEntries(dir: string): Promise<string[]> {
|
|
@@ -60,6 +93,40 @@ async function readEntries(dir: string): Promise<string[]> {
|
|
|
60
93
|
return paths.sort()
|
|
61
94
|
}
|
|
62
95
|
|
|
96
|
+
export interface FolderResolution {
|
|
97
|
+
/** Every folder that resolved, with the nested splits beneath each. */
|
|
98
|
+
readonly folders: readonly AuditedFolder[]
|
|
99
|
+
/**
|
|
100
|
+
* Requested names that resolved under no base, reported rather than dropped.
|
|
101
|
+
* Which absences are worth saying out loud is the caller's judgment: a
|
|
102
|
+
* default folder a project does not carry is ordinary, and a name passed by
|
|
103
|
+
* hand that resolves nowhere is a typo that would otherwise read as a pass.
|
|
104
|
+
*/
|
|
105
|
+
readonly missing: readonly string[]
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface ResolveOptions {
|
|
109
|
+
/**
|
|
110
|
+
* Whether a name may resolve at the project root when `.claude/` does not
|
|
111
|
+
* carry it. False for the default list, which names three folders a project
|
|
112
|
+
* is expected to hold under `.claude/` and nowhere else.
|
|
113
|
+
*/
|
|
114
|
+
readonly canResolveAtRoot?: boolean
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function locate(
|
|
118
|
+
root: string,
|
|
119
|
+
name: string,
|
|
120
|
+
bases: readonly string[],
|
|
121
|
+
): { readonly dir: string; readonly base: string } | undefined {
|
|
122
|
+
for (const base of bases) {
|
|
123
|
+
const dir = resolve(root, base, name)
|
|
124
|
+
if (existsSync(`${dir}/${INDEX_FILE}`)) return { dir, base }
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return undefined
|
|
128
|
+
}
|
|
129
|
+
|
|
63
130
|
/**
|
|
64
131
|
* Resolves the folders to audit under `root`.
|
|
65
132
|
*
|
|
@@ -67,33 +134,49 @@ async function readEntries(dir: string): Promise<string[]> {
|
|
|
67
134
|
* folder beneath it, so a domain that outgrew one file and split is audited at
|
|
68
135
|
* the same grain as one that did not. Discovery of the nested folders runs
|
|
69
136
|
* through the shared walker, which is what keeps `.gitignore` and the vendored
|
|
70
|
-
* prune governing this scan as well as index regeneration.
|
|
137
|
+
* prune governing this scan as well as index regeneration. That prune is what
|
|
138
|
+
* lets a root folder be walked at all, since a name at the project root sits
|
|
139
|
+
* beside `node_modules` and a build output.
|
|
71
140
|
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
141
|
+
* The project root is reached only when the caller opts in, so a target holding
|
|
142
|
+
* a root `wireframes/` is not audited against a standard it never adopted by
|
|
143
|
+
* the mere act of running the command. `.claude/` still wins a name carried by
|
|
144
|
+
* both, and the scope line prints the resolved path so a caller reads which
|
|
145
|
+
* base was taken rather than inferring it.
|
|
146
|
+
*
|
|
147
|
+
* Nothing above this asks where a folder came from. A name that resolves at the
|
|
148
|
+
* root is measured by every rule that generalizes and gated out of the rules a
|
|
149
|
+
* single standard carries, which `governsContent` decides from the name.
|
|
75
150
|
*/
|
|
76
151
|
export async function resolveFolders(
|
|
77
152
|
root: string,
|
|
78
153
|
names: readonly string[] = DEFAULT_FOLDERS,
|
|
79
|
-
|
|
154
|
+
{ canResolveAtRoot = false }: ResolveOptions = {},
|
|
155
|
+
): Promise<FolderResolution> {
|
|
156
|
+
const bases = canResolveAtRoot ? [CLAUDE_BASE, ROOT_BASE] : [CLAUDE_BASE]
|
|
80
157
|
const folders: AuditedFolder[] = []
|
|
158
|
+
const missing: string[] = []
|
|
81
159
|
|
|
82
160
|
for (const name of names) {
|
|
83
|
-
const
|
|
84
|
-
if (!
|
|
161
|
+
const found = locate(root, name, bases)
|
|
162
|
+
if (!found) {
|
|
163
|
+
missing.push(name)
|
|
164
|
+
continue
|
|
165
|
+
}
|
|
85
166
|
|
|
86
|
-
const dirs = [dir, ...(await listIndexes(dir)).map(dirname)]
|
|
167
|
+
const dirs = [found.dir, ...(await listIndexes(found.dir)).map(dirname)]
|
|
87
168
|
|
|
88
169
|
for (const each of [...new Set(dirs)].sort()) {
|
|
89
170
|
folders.push({
|
|
90
171
|
name,
|
|
172
|
+
base: found.base,
|
|
91
173
|
rel: relative(root, each),
|
|
92
174
|
indexPath: `${each}/${INDEX_FILE}`,
|
|
93
175
|
entries: await readEntries(each),
|
|
176
|
+
nested: each !== found.dir,
|
|
94
177
|
})
|
|
95
178
|
}
|
|
96
179
|
}
|
|
97
180
|
|
|
98
|
-
return folders
|
|
181
|
+
return { folders, missing }
|
|
99
182
|
}
|
|
@@ -5,7 +5,13 @@ description: GitHub Actions workflow triggers and checks
|
|
|
5
5
|
|
|
6
6
|
# CI
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Owns the GitHub Actions workflow that gates a merge: which events start a run, and which checks have to pass before the branch can land. The checks call package scripts rather than defining commands of their own, so what each one runs is the development entry's subject.
|
|
11
|
+
|
|
12
|
+
## Layout
|
|
13
|
+
|
|
14
|
+
- `.github/workflows/` owns the workflow definitions a trigger below starts
|
|
9
15
|
|
|
10
16
|
## Triggers
|
|
11
17
|
|
|
@@ -5,7 +5,14 @@ description: Local dev workflow, scripts, and husky hooks
|
|
|
5
5
|
|
|
6
6
|
# Development
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Owns how the project runs on a developer machine: installing the toolchain, the scripts that verify a change, and the git hooks that run them before a commit or a push leaves. CI calls the same scripts from a workflow, which is the CI entry's subject.
|
|
11
|
+
|
|
12
|
+
## Layout
|
|
13
|
+
|
|
14
|
+
- `scripts/` owns the shell scripts the package scripts below call
|
|
15
|
+
- `.husky/` owns the git hooks
|
|
9
16
|
|
|
10
17
|
## Setup
|
|
11
18
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Context
|
|
3
|
+
subtitle: Per-domain narrative loaded on demand
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Context
|
|
7
|
+
|
|
8
|
+
Per-domain narrative loaded on demand
|
|
9
|
+
|
|
10
|
+
- [CI](ci.md): GitHub Actions workflow triggers and checks
|
|
11
|
+
- [Development](development.md): Local dev workflow, scripts, and husky hooks
|