@crouton-kit/crouter 0.1.1 → 0.1.2
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/bin/crouter +2 -0
- package/bin/crtr +2 -0
- package/dist/cli.js +34 -4
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.js +126 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +216 -0
- package/dist/commands/marketplace.d.ts +2 -0
- package/dist/commands/marketplace.js +365 -0
- package/dist/commands/plan.d.ts +2 -0
- package/dist/commands/plan.js +9 -0
- package/dist/commands/plugin.d.ts +2 -0
- package/dist/commands/plugin.js +364 -0
- package/dist/commands/skill.d.ts +2 -0
- package/dist/commands/skill.js +404 -0
- package/dist/commands/spec.d.ts +2 -0
- package/dist/commands/spec.js +9 -0
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.js +140 -0
- package/dist/core/artifact.d.ts +14 -0
- package/dist/core/artifact.js +187 -0
- package/dist/core/config.d.ts +10 -0
- package/dist/core/config.js +83 -0
- package/dist/core/errors.d.ts +12 -0
- package/dist/core/errors.js +28 -0
- package/dist/core/frontmatter.d.ts +8 -0
- package/dist/core/frontmatter.js +84 -0
- package/dist/core/fs-utils.d.ts +18 -0
- package/dist/core/fs-utils.js +115 -0
- package/dist/core/git.d.ts +18 -0
- package/dist/core/git.js +71 -0
- package/dist/core/manifest.d.ts +5 -0
- package/dist/core/manifest.js +15 -0
- package/dist/core/output.d.ts +35 -0
- package/dist/core/output.js +99 -0
- package/dist/core/resolver.d.ts +28 -0
- package/dist/core/resolver.js +228 -0
- package/dist/core/scope.d.ts +12 -0
- package/dist/core/scope.js +87 -0
- package/dist/prompts/plan.d.ts +1 -0
- package/dist/prompts/plan.js +99 -0
- package/dist/prompts/spec.d.ts +1 -0
- package/dist/prompts/spec.js +106 -0
- package/dist/types.d.ts +114 -0
- package/dist/types.js +33 -0
- package/package.json +8 -5
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
export function specPrompt(specsDir) {
|
|
2
|
+
return `# Spec workflow
|
|
3
|
+
|
|
4
|
+
You are entering a focused spec session. The goal is to produce a design +
|
|
5
|
+
requirements spec — a document describing **what** to build, the shape of the
|
|
6
|
+
solution, and the behaviors it must satisfy. A spec is upstream of a plan: it
|
|
7
|
+
captures decisions, not implementation steps.
|
|
8
|
+
|
|
9
|
+
Specs for this directory live at:
|
|
10
|
+
${specsDir}
|
|
11
|
+
|
|
12
|
+
If a relevant prior spec already exists there, read it first. Treat an
|
|
13
|
+
existing spec as the starting point — extend or revise rather than restart.
|
|
14
|
+
|
|
15
|
+
## Phase 1: Shape
|
|
16
|
+
|
|
17
|
+
Build a comprehensive picture of the problem and the relevant code. Surface
|
|
18
|
+
existing patterns, constraints, and prior decisions.
|
|
19
|
+
|
|
20
|
+
- **Launch up to 3 Explore subagents IN PARALLEL** (single message, multiple
|
|
21
|
+
tool calls) to cover the codebase efficiently.
|
|
22
|
+
- Use 1 agent for narrow, well-scoped problems.
|
|
23
|
+
- Use multiple agents when the spec touches several subsystems or you need
|
|
24
|
+
to compare existing implementations.
|
|
25
|
+
- Quality over quantity — 3 agents maximum.
|
|
26
|
+
|
|
27
|
+
After exploration, draft a high-level design in your head: the shape of the
|
|
28
|
+
solution, the new or changed pieces, the boundaries.
|
|
29
|
+
|
|
30
|
+
## Phase 2: Requirements
|
|
31
|
+
|
|
32
|
+
Translate the shape into concrete behavioral requirements. Each requirement
|
|
33
|
+
should be:
|
|
34
|
+
|
|
35
|
+
- **Testable** — has a clear pass/fail condition.
|
|
36
|
+
- **Behavior-focused** — describes what the system does, not how.
|
|
37
|
+
- **Scoped** — covers one observable behavior.
|
|
38
|
+
|
|
39
|
+
Prefer EARS-style phrasing where it fits (\`When <trigger>, the system shall
|
|
40
|
+
<behavior>\`), but do not force it. Group requirements by capability.
|
|
41
|
+
|
|
42
|
+
You may launch a Plan agent to draft requirements for a specific capability
|
|
43
|
+
in parallel, but for small specs writing them yourself is usually faster.
|
|
44
|
+
|
|
45
|
+
## Phase 3: Deepen
|
|
46
|
+
|
|
47
|
+
- Read the critical files identified during Phase 1 to deepen your
|
|
48
|
+
understanding before locking decisions.
|
|
49
|
+
- Reconcile the requirements against the shape — if a requirement reveals a
|
|
50
|
+
gap in the design, refine the design before saving.
|
|
51
|
+
- Use **AskUserQuestion** for any remaining ambiguities. Bias toward asking
|
|
52
|
+
when a decision is non-obvious or when the user's intent is genuinely
|
|
53
|
+
unclear.
|
|
54
|
+
|
|
55
|
+
**Important:** Use AskUserQuestion ONLY to clarify requirements or choose
|
|
56
|
+
between approaches. Never use it to ask "is this spec okay?" or "should I
|
|
57
|
+
save?" — the save step below is the approval moment.
|
|
58
|
+
|
|
59
|
+
## Phase 4: Save
|
|
60
|
+
|
|
61
|
+
Save the spec with \`crtr spec --name <kebab-case-name>\`. Pipe the markdown
|
|
62
|
+
body in via stdin (heredoc):
|
|
63
|
+
|
|
64
|
+
\`\`\`bash
|
|
65
|
+
crtr spec --name <kebab-case-name> <<'EOF'
|
|
66
|
+
# Spec: <one-line title>
|
|
67
|
+
|
|
68
|
+
## Context
|
|
69
|
+
<the problem this spec addresses, what motivates it, and the intended
|
|
70
|
+
outcome. Include relevant constraints — user goals, stakeholders, deadlines.>
|
|
71
|
+
|
|
72
|
+
## Design
|
|
73
|
+
<the shape of the solution. Components, data flow, key decisions and why
|
|
74
|
+
they were chosen. Reference existing code with \`file_path:line_number\`.>
|
|
75
|
+
|
|
76
|
+
## Requirements
|
|
77
|
+
<grouped behavioral requirements. Each one testable.>
|
|
78
|
+
|
|
79
|
+
### <Capability A>
|
|
80
|
+
- When <trigger>, the system shall <behavior>.
|
|
81
|
+
- ...
|
|
82
|
+
|
|
83
|
+
### <Capability B>
|
|
84
|
+
- ...
|
|
85
|
+
|
|
86
|
+
## Out of scope
|
|
87
|
+
<things explicitly NOT covered, so the next reader knows where the edges
|
|
88
|
+
are.>
|
|
89
|
+
|
|
90
|
+
## Open questions
|
|
91
|
+
<anything you could not resolve. Empty if all decisions are pinned.>
|
|
92
|
+
EOF
|
|
93
|
+
\`\`\`
|
|
94
|
+
|
|
95
|
+
- Pick a short, descriptive kebab-case name. Names may be nested
|
|
96
|
+
(\`crtr spec --name auth/refresh-tokens\`).
|
|
97
|
+
- The file lands at \`${specsDir}/<name>.md\`.
|
|
98
|
+
- If you are running inside tmux, the saved spec auto-opens in a side pane
|
|
99
|
+
via termrender. No extra step needed.
|
|
100
|
+
|
|
101
|
+
## Phase 5: Done
|
|
102
|
+
|
|
103
|
+
Your turn ends after the save command succeeds. No need to summarize the spec
|
|
104
|
+
in chat — the user can read the file.
|
|
105
|
+
`;
|
|
106
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
export type Scope = 'user' | 'project';
|
|
2
|
+
export declare const ExitCode: {
|
|
3
|
+
readonly SUCCESS: 0;
|
|
4
|
+
readonly GENERAL: 1;
|
|
5
|
+
readonly USAGE: 2;
|
|
6
|
+
readonly NOT_FOUND: 3;
|
|
7
|
+
readonly AMBIGUOUS: 4;
|
|
8
|
+
readonly NETWORK: 5;
|
|
9
|
+
};
|
|
10
|
+
export type ExitCodeValue = (typeof ExitCode)[keyof typeof ExitCode];
|
|
11
|
+
export declare const SCHEMA_VERSION = 1;
|
|
12
|
+
export interface OwnerRef {
|
|
13
|
+
name?: string;
|
|
14
|
+
email?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface PluginManifest {
|
|
17
|
+
name: string;
|
|
18
|
+
version?: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
source?: string;
|
|
21
|
+
owner?: OwnerRef;
|
|
22
|
+
kinds?: string[];
|
|
23
|
+
}
|
|
24
|
+
export interface MarketplacePluginEntry {
|
|
25
|
+
name: string;
|
|
26
|
+
source: string;
|
|
27
|
+
version?: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
keywords?: string[];
|
|
30
|
+
}
|
|
31
|
+
export interface MarketplaceManifest {
|
|
32
|
+
name: string;
|
|
33
|
+
version?: string;
|
|
34
|
+
owner?: OwnerRef;
|
|
35
|
+
plugins: MarketplacePluginEntry[];
|
|
36
|
+
}
|
|
37
|
+
export interface ConfigMarketplaceEntry {
|
|
38
|
+
url: string;
|
|
39
|
+
ref: string;
|
|
40
|
+
installed_at: string;
|
|
41
|
+
}
|
|
42
|
+
export interface ConfigPluginEntry {
|
|
43
|
+
enabled: boolean;
|
|
44
|
+
source_marketplace?: string;
|
|
45
|
+
version?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface ConfigSkillEntry {
|
|
48
|
+
enabled: boolean;
|
|
49
|
+
}
|
|
50
|
+
export interface AutoUpdateConfig {
|
|
51
|
+
crtr: boolean;
|
|
52
|
+
content: 'notify' | 'apply' | false;
|
|
53
|
+
interval_hours: number;
|
|
54
|
+
}
|
|
55
|
+
export interface ScopeConfig {
|
|
56
|
+
schema_version: number;
|
|
57
|
+
marketplaces: Record<string, ConfigMarketplaceEntry>;
|
|
58
|
+
plugins: Record<string, ConfigPluginEntry>;
|
|
59
|
+
skills: Record<string, ConfigSkillEntry>;
|
|
60
|
+
auto_update: AutoUpdateConfig;
|
|
61
|
+
}
|
|
62
|
+
export interface ScopeState {
|
|
63
|
+
marketplaces: Record<string, {
|
|
64
|
+
last_updated?: string;
|
|
65
|
+
}>;
|
|
66
|
+
plugins: Record<string, {
|
|
67
|
+
last_updated?: string;
|
|
68
|
+
}>;
|
|
69
|
+
last_self_check?: string;
|
|
70
|
+
}
|
|
71
|
+
export interface SkillFrontmatter {
|
|
72
|
+
name: string;
|
|
73
|
+
description?: string;
|
|
74
|
+
keywords?: string[];
|
|
75
|
+
}
|
|
76
|
+
export interface Skill {
|
|
77
|
+
name: string;
|
|
78
|
+
plugin: string;
|
|
79
|
+
scope: Scope;
|
|
80
|
+
path: string;
|
|
81
|
+
pluginRoot: string;
|
|
82
|
+
frontmatter: SkillFrontmatter;
|
|
83
|
+
enabled: boolean;
|
|
84
|
+
disabledIn?: Scope;
|
|
85
|
+
}
|
|
86
|
+
export interface InstalledPlugin {
|
|
87
|
+
name: string;
|
|
88
|
+
scope: Scope;
|
|
89
|
+
root: string;
|
|
90
|
+
manifest: PluginManifest;
|
|
91
|
+
enabled: boolean;
|
|
92
|
+
sourceMarketplace?: string;
|
|
93
|
+
version?: string;
|
|
94
|
+
}
|
|
95
|
+
export interface InstalledMarketplace {
|
|
96
|
+
name: string;
|
|
97
|
+
scope: Scope;
|
|
98
|
+
root: string;
|
|
99
|
+
manifest: MarketplaceManifest;
|
|
100
|
+
url: string;
|
|
101
|
+
ref: string;
|
|
102
|
+
}
|
|
103
|
+
export declare const PLUGIN_MANIFEST_DIR = ".crouter-plugin";
|
|
104
|
+
export declare const PLUGIN_MANIFEST_FILE = "plugin.json";
|
|
105
|
+
export declare const MARKETPLACE_MANIFEST_DIR = ".crouter-marketplace";
|
|
106
|
+
export declare const MARKETPLACE_MANIFEST_FILE = "marketplace.json";
|
|
107
|
+
export declare const CRTR_DIR_NAME = ".crouter";
|
|
108
|
+
export declare const CONFIG_FILE = "config.json";
|
|
109
|
+
export declare const STATE_FILE = "state.json";
|
|
110
|
+
export declare const SKILL_ENTRY_FILE = "SKILL.md";
|
|
111
|
+
export declare const SKILLS_DIR = "skills";
|
|
112
|
+
export declare function defaultScopeConfig(): ScopeConfig;
|
|
113
|
+
export declare function skillConfigKey(plugin: string, name: string): string;
|
|
114
|
+
export declare function defaultScopeState(): ScopeState;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const ExitCode = {
|
|
2
|
+
SUCCESS: 0,
|
|
3
|
+
GENERAL: 1,
|
|
4
|
+
USAGE: 2,
|
|
5
|
+
NOT_FOUND: 3,
|
|
6
|
+
AMBIGUOUS: 4,
|
|
7
|
+
NETWORK: 5,
|
|
8
|
+
};
|
|
9
|
+
export const SCHEMA_VERSION = 1;
|
|
10
|
+
export const PLUGIN_MANIFEST_DIR = '.crouter-plugin';
|
|
11
|
+
export const PLUGIN_MANIFEST_FILE = 'plugin.json';
|
|
12
|
+
export const MARKETPLACE_MANIFEST_DIR = '.crouter-marketplace';
|
|
13
|
+
export const MARKETPLACE_MANIFEST_FILE = 'marketplace.json';
|
|
14
|
+
export const CRTR_DIR_NAME = '.crouter';
|
|
15
|
+
export const CONFIG_FILE = 'config.json';
|
|
16
|
+
export const STATE_FILE = 'state.json';
|
|
17
|
+
export const SKILL_ENTRY_FILE = 'SKILL.md';
|
|
18
|
+
export const SKILLS_DIR = 'skills';
|
|
19
|
+
export function defaultScopeConfig() {
|
|
20
|
+
return {
|
|
21
|
+
schema_version: SCHEMA_VERSION,
|
|
22
|
+
marketplaces: {},
|
|
23
|
+
plugins: {},
|
|
24
|
+
skills: {},
|
|
25
|
+
auto_update: { crtr: true, content: 'notify', interval_hours: 24 },
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export function skillConfigKey(plugin, name) {
|
|
29
|
+
return `${plugin}:${name}`;
|
|
30
|
+
}
|
|
31
|
+
export function defaultScopeState() {
|
|
32
|
+
return { marketplaces: {}, plugins: {} };
|
|
33
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crouton-kit/crouter",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "crtr — fast access to skills, plugins, and marketplaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"bin": {
|
|
9
|
-
"
|
|
9
|
+
"crtr": "bin/crtr",
|
|
10
|
+
"crouter": "bin/crouter"
|
|
10
11
|
},
|
|
11
12
|
"exports": {
|
|
12
13
|
".": {
|
|
@@ -18,12 +19,14 @@
|
|
|
18
19
|
}
|
|
19
20
|
},
|
|
20
21
|
"files": [
|
|
21
|
-
"dist"
|
|
22
|
+
"dist",
|
|
23
|
+
"bin"
|
|
22
24
|
],
|
|
23
25
|
"scripts": {
|
|
24
26
|
"build": "tsc",
|
|
25
27
|
"dev": "tsx src/cli.ts",
|
|
26
|
-
"link": "npm link"
|
|
28
|
+
"link": "npm link",
|
|
29
|
+
"prepublishOnly": "npm run build"
|
|
27
30
|
},
|
|
28
31
|
"repository": {
|
|
29
32
|
"type": "git",
|