@hasna/skills 0.1.53 → 0.1.55
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/index.js +668 -40
- package/bin/mcp.js +549 -8
- package/dist/cli/cli.test-utils.d.ts +1 -0
- package/dist/cli/commands/tool-primitives.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +541 -19
- package/dist/lib/cli-mcp-parity.d.ts +1 -1
- package/dist/lib/tool-primitives.d.ts +63 -0
- package/package.json +1 -1
- package/skills/apidocs/.claude/settings.json +5 -0
- package/skills/project-dashboard-reports/SKILL.md +1 -1
- package/skills/project-dashboard-reports/src/index.ts +1 -1
- package/skills/todos-plan/SKILL.md +194 -0
- package/skills/todos-plan/agents/openai.yaml +4 -0
- package/skills/todos-plan/package.json +9 -0
- package/skills/todos-plan/src/index.ts +68 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type SkillsCliMcpParityDomain = "discovery" | "portable-skills" | "runtime" | "validation";
|
|
1
|
+
export type SkillsCliMcpParityDomain = "discovery" | "portable-skills" | "runtime" | "tool-primitives" | "validation";
|
|
2
2
|
export interface SkillsCliMcpParityEntry {
|
|
3
3
|
domain: SkillsCliMcpParityDomain;
|
|
4
4
|
operation: string;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { type SkillMeta, type SkillRegistryProfile } from "./registry.js";
|
|
2
|
+
export declare const TOOL_PRIMITIVE_SCHEMA_VERSION: 1;
|
|
3
|
+
export type ToolPrimitiveRuntime = "local" | "hosted" | "gateway" | "connector" | "mixed";
|
|
4
|
+
export interface ToolPrimitive {
|
|
5
|
+
name: string;
|
|
6
|
+
title: string;
|
|
7
|
+
family: string;
|
|
8
|
+
description: string;
|
|
9
|
+
runtime: ToolPrimitiveRuntime;
|
|
10
|
+
stable: true;
|
|
11
|
+
cliCommands: string[];
|
|
12
|
+
mcpTools: string[];
|
|
13
|
+
apiSurfaces: string[];
|
|
14
|
+
envVars: string[];
|
|
15
|
+
outputTypes: string[];
|
|
16
|
+
capabilities: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface ToolPrimitiveSummary {
|
|
19
|
+
name: string;
|
|
20
|
+
title: string;
|
|
21
|
+
family: string;
|
|
22
|
+
runtime: ToolPrimitiveRuntime;
|
|
23
|
+
description: string;
|
|
24
|
+
}
|
|
25
|
+
export interface SkillToolDependency {
|
|
26
|
+
skill: string;
|
|
27
|
+
primitive: string;
|
|
28
|
+
family: string;
|
|
29
|
+
required: boolean;
|
|
30
|
+
reason: string;
|
|
31
|
+
}
|
|
32
|
+
export interface SkillToolDependencies {
|
|
33
|
+
schemaVersion: typeof TOOL_PRIMITIVE_SCHEMA_VERSION;
|
|
34
|
+
skill: string;
|
|
35
|
+
category: string;
|
|
36
|
+
source: SkillMeta["source"] | "official";
|
|
37
|
+
dependencies: SkillToolDependency[];
|
|
38
|
+
gatewayBacked: boolean;
|
|
39
|
+
hostedRuntime: boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface ToolPrimitiveCoverageIssue {
|
|
42
|
+
skill: string;
|
|
43
|
+
code: "skill.unmapped" | "primitive.missing";
|
|
44
|
+
message: string;
|
|
45
|
+
}
|
|
46
|
+
export interface ToolPrimitiveCoverageResult {
|
|
47
|
+
schemaVersion: typeof TOOL_PRIMITIVE_SCHEMA_VERSION;
|
|
48
|
+
valid: boolean;
|
|
49
|
+
profile: SkillRegistryProfile;
|
|
50
|
+
skillCount: number;
|
|
51
|
+
primitiveCount: number;
|
|
52
|
+
mappedSkillCount: number;
|
|
53
|
+
gatewayBackedSkillCount: number;
|
|
54
|
+
hostedRuntimeSkillCount: number;
|
|
55
|
+
issues: ToolPrimitiveCoverageIssue[];
|
|
56
|
+
}
|
|
57
|
+
export declare const TOOL_PRIMITIVES: ToolPrimitive[];
|
|
58
|
+
export declare function listToolPrimitives(query?: string): ToolPrimitiveSummary[];
|
|
59
|
+
export declare function getToolPrimitive(name: string): ToolPrimitive | undefined;
|
|
60
|
+
export declare function getSkillToolDependencies(name: string): SkillToolDependencies | null;
|
|
61
|
+
export declare function createSkillToolDependencies(skill: SkillMeta): SkillToolDependencies;
|
|
62
|
+
export declare function isGatewayBackedSkill(name: string): boolean;
|
|
63
|
+
export declare function validateToolPrimitiveCoverage(profile?: SkillRegistryProfile): ToolPrimitiveCoverageResult;
|
package/package.json
CHANGED
|
@@ -46,7 +46,7 @@ Provider CLIs should emit bounded `hasna.project_panel.v1` JSON:
|
|
|
46
46
|
```bash
|
|
47
47
|
todos project-panel --project <project> --json --contract
|
|
48
48
|
files project-panel --project <project> --json --contract
|
|
49
|
-
mailery
|
|
49
|
+
mailery project-panel --project <project> --limit 20 --json --contract
|
|
50
50
|
conversations project-panel --project <project> --limit 30 --json --contract
|
|
51
51
|
knowledge project-panel --project <project> --scope project --limit 30 --json --contract
|
|
52
52
|
mementos --json project-panel --project <project> --contract
|
|
@@ -29,7 +29,7 @@ const sections: GuideSection[] = [
|
|
|
29
29
|
items: [
|
|
30
30
|
"todos project-panel --project <project> --json --contract",
|
|
31
31
|
"files project-panel --project <project> --json --contract",
|
|
32
|
-
"mailery
|
|
32
|
+
"mailery project-panel --project <project> --limit 20 --json --contract",
|
|
33
33
|
"conversations project-panel --project <project> --limit 30 --json --contract",
|
|
34
34
|
"knowledge project-panel --project <project> --scope project --limit 30 --json --contract",
|
|
35
35
|
"mementos --json project-panel --project <project> --contract",
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: todos-plan
|
|
3
|
+
description: Use when Codewith needs to create, edit, save, verify, execute, route, or sync todos plans for local @hasna/todos work or hosted todos.md/platform-todos work. Triggers include todos plan authoring, local plan Markdown files, plan IDs, task-triggered workers, launch verification checklists, platform plan sync, dry-run plan generation, and updating Codewith workers that must use Todos CLI task IDs as source of truth.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Todos Plan
|
|
7
|
+
|
|
8
|
+
Use the Todos CLI as the source of truth. Markdown plan files are durable
|
|
9
|
+
human-readable artifacts; they do not replace task or plan rows. Never edit
|
|
10
|
+
SQLite, RDS rows, or generated task stores directly.
|
|
11
|
+
|
|
12
|
+
## Known Launch Plans
|
|
13
|
+
|
|
14
|
+
- Platform launch plan: `fc27c6c1-7f26-4bea-bbda-dc0731a9d972`
|
|
15
|
+
- Codewith skills plan: `4bc933b6-8b0a-4e38-8807-aa11b034a9af`
|
|
16
|
+
|
|
17
|
+
When a prompt includes task IDs, inspect and update each task one at a time:
|
|
18
|
+
Commands containing angle-bracket placeholders are illustrative; replace the
|
|
19
|
+
placeholders with real task, plan, org, or file values before running them.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
todos plans --show <plan-id>
|
|
23
|
+
todos inspect <task-id>
|
|
24
|
+
todos --agent <agent> start <task-id>
|
|
25
|
+
todos comment <task-id> "Progress note"
|
|
26
|
+
todos record-verification <task-id> "<command>" --status passed --summary "<summary>" --agent <agent>
|
|
27
|
+
todos --agent <agent> done <task-id> --files-changed "<paths>" --test-results "<results>" --notes "<notes>"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Authoring Workflow
|
|
31
|
+
|
|
32
|
+
1. Start a native Codewith goal for non-trivial work.
|
|
33
|
+
2. Read the relevant plan with `todos plans --show <plan-id>`.
|
|
34
|
+
3. Inspect the current task before editing anything.
|
|
35
|
+
4. Create or update the local Markdown artifact under
|
|
36
|
+
`.hasna/todos/plans/<project-id>/<plan-slug>.md`.
|
|
37
|
+
5. Use CLI commands for task/plan state changes:
|
|
38
|
+
`todos plans --add`, `todos add --plan`, `todos update`,
|
|
39
|
+
`todos comment`, `todos record-verification`, and `todos done`.
|
|
40
|
+
6. Use the Markdown file for intent, acceptance criteria, dependency notes,
|
|
41
|
+
rollout notes, and evidence links.
|
|
42
|
+
7. Run validation commands and record them on the task.
|
|
43
|
+
8. Complete only the task whose acceptance criteria are satisfied.
|
|
44
|
+
|
|
45
|
+
Use direct file edits for plan text. Use Todos CLI for state transitions,
|
|
46
|
+
assignments, comments, dependencies, and verification evidence.
|
|
47
|
+
|
|
48
|
+
## Local Plan Files
|
|
49
|
+
|
|
50
|
+
Preferred location:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
.hasna/todos/plans/<project-id>/<plan-slug>.md
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Use stable lowercase slugs. Include the Todos plan ID when one exists. If a
|
|
57
|
+
plan is still draft-only, set `plan_id: pending` and create or link the plan
|
|
58
|
+
before workers execute it.
|
|
59
|
+
|
|
60
|
+
Example:
|
|
61
|
+
|
|
62
|
+
```markdown
|
|
63
|
+
---
|
|
64
|
+
plan_id: 4bc933b6-8b0a-4e38-8807-aa11b034a9af
|
|
65
|
+
project_id: open-skills
|
|
66
|
+
plan_slug: codewith-todos-plan-skills
|
|
67
|
+
status: active
|
|
68
|
+
source: todos-cli
|
|
69
|
+
updated: 2026-06-30
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
# Codewith Todos Plan Skills
|
|
73
|
+
|
|
74
|
+
## Scope
|
|
75
|
+
- Create a `todos-plan` Codewith skill.
|
|
76
|
+
- Sync it to the active Codewith skills directory.
|
|
77
|
+
|
|
78
|
+
## Tasks
|
|
79
|
+
- [ ] `4a32ec84` Define authoring workflow.
|
|
80
|
+
- [ ] `36e08375` Document local plan file naming.
|
|
81
|
+
- [ ] `904a4e78` Validate command examples.
|
|
82
|
+
|
|
83
|
+
## Status Transitions
|
|
84
|
+
- `pending`: task is not started.
|
|
85
|
+
- `in_progress`: one agent owns it and has a lock.
|
|
86
|
+
- `blocked`: a named prerequisite is missing.
|
|
87
|
+
- `completed`: verification is recorded and accepted.
|
|
88
|
+
|
|
89
|
+
## Verification
|
|
90
|
+
- `python3 .../quick_validate.py skills/todos-plan`
|
|
91
|
+
- `todos plans --show 4bc933b6-8b0a-4e38-8807-aa11b034a9af`
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Hosted Sync
|
|
95
|
+
|
|
96
|
+
Hosted sync is explicit. Confirm tenant, auth, and billing before writing.
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
platform-todos --json auth status
|
|
100
|
+
platform-todos --json auth whoami
|
|
101
|
+
platform-todos --json billing status
|
|
102
|
+
platform-todos docs catalog --surface api --json
|
|
103
|
+
platform-todos docs catalog --surface mcp --json
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Preview first:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
platform-todos plans generate \
|
|
110
|
+
--org <organization-id> \
|
|
111
|
+
--objective "Create project tasks, dependencies, and verification gates" \
|
|
112
|
+
--dry-run true \
|
|
113
|
+
--approval-before-create true
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Create only after approval:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
platform-todos plans generate \
|
|
120
|
+
--org <organization-id> \
|
|
121
|
+
--objective "Create project tasks, dependencies, and verification gates" \
|
|
122
|
+
--dry-run false \
|
|
123
|
+
--approval-before-create true
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
For local imports, prefer a dry run and a conflict strategy:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
platform-todos import local-sqlite <manifest.json> \
|
|
130
|
+
--org <organization-id> \
|
|
131
|
+
--dry-run true \
|
|
132
|
+
--conflict-strategy skip \
|
|
133
|
+
--idempotency-key <stable-key>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Record evidence on the task: command, status, org/project ID, plan ID, and
|
|
137
|
+
artifact path. Do not record API keys, raw tokens, secret values, or private
|
|
138
|
+
payloads.
|
|
139
|
+
|
|
140
|
+
## Worker Routing
|
|
141
|
+
|
|
142
|
+
Task-triggered launch workers must receive:
|
|
143
|
+
|
|
144
|
+
- task ID and plan ID
|
|
145
|
+
- repo path and allowed paths
|
|
146
|
+
- source-of-truth instruction: use Todos CLI, not messages or tmux panes
|
|
147
|
+
- native Codewith goal requirement
|
|
148
|
+
- validation gates and evidence expectations
|
|
149
|
+
- explicit out-of-scope paths
|
|
150
|
+
- requirement for adversarial verification before completion
|
|
151
|
+
|
|
152
|
+
Use isolated work scopes. Do not route new repo-mutating work by pasting prompts
|
|
153
|
+
into existing tmux panes. If the routing automation is missing, create a task
|
|
154
|
+
for the missing automation instead of using a hidden fallback.
|
|
155
|
+
|
|
156
|
+
Prompt shape:
|
|
157
|
+
|
|
158
|
+
```text
|
|
159
|
+
Task: <task-id>
|
|
160
|
+
Plan: <plan-id>
|
|
161
|
+
Repo: <absolute-path>
|
|
162
|
+
Allowed paths: <paths>
|
|
163
|
+
Out of scope: <paths>
|
|
164
|
+
Use Todos CLI as source of truth.
|
|
165
|
+
Start a native Codewith goal.
|
|
166
|
+
Record verification and changed files on the task before done.
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Launch Checklist
|
|
170
|
+
|
|
171
|
+
For todos.md launch tasks, verify the relevant surfaces and record evidence:
|
|
172
|
+
|
|
173
|
+
- Auth: `platform-todos auth login`, `auth status`, `auth whoami`, API key
|
|
174
|
+
creation/revocation/rotation.
|
|
175
|
+
- Billing: `platform-todos billing status`, `usage`, `checkout`, `portal`,
|
|
176
|
+
Stripe webhook lifecycle, quota errors.
|
|
177
|
+
- Plan CRUD: local `todos plans --add/show`, hosted `platform-todos plans
|
|
178
|
+
templates/create/generate/refine`, dry-run before create.
|
|
179
|
+
- Hosted runs: list/create/show/logs/artifacts/cancel plus controls, pause,
|
|
180
|
+
resume, emergency stop, usage evidence, and sandbox policy.
|
|
181
|
+
- Audit export: redacted export command, hash/manifest evidence, no secrets.
|
|
182
|
+
- Storage: signed upload/download/delete/export behavior and quota gates.
|
|
183
|
+
- Landing and docs: desktop/mobile screenshot review, docs links, billing entry,
|
|
184
|
+
no unsupported dashboard or OAuth promises.
|
|
185
|
+
|
|
186
|
+
## Done Criteria
|
|
187
|
+
|
|
188
|
+
- The plan file is under `.hasna/todos/plans/<project-id>/`.
|
|
189
|
+
- Todos CLI reflects the task/plan state.
|
|
190
|
+
- Command examples were run or clearly marked illustrative.
|
|
191
|
+
- Verification is recorded with `todos record-verification`.
|
|
192
|
+
- Changed files and residual risks are noted on the task.
|
|
193
|
+
- For substantial work, an adversarial verifier or explicit adversarial
|
|
194
|
+
self-review is reconciled before marking the task done.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
|
|
4
|
+
const CHECKLIST = [
|
|
5
|
+
"Read the Todos plan with: todos plans --show <plan-id>",
|
|
6
|
+
"Inspect and start exactly one task before editing.",
|
|
7
|
+
"Keep the Markdown plan artifact under .hasna/todos/plans/<project-id>/.",
|
|
8
|
+
"Use Todos CLI for task status, comments, dependencies, and verification.",
|
|
9
|
+
"Record validation evidence before marking a task done.",
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
function usage(): string {
|
|
13
|
+
return [
|
|
14
|
+
"todos-plan - plan authoring helper for Todos CLI source-of-truth workflows",
|
|
15
|
+
"",
|
|
16
|
+
"Usage:",
|
|
17
|
+
" todos-plan checklist",
|
|
18
|
+
" todos-plan path <project-id> <plan-slug>",
|
|
19
|
+
" todos-plan show <plan-id>",
|
|
20
|
+
"",
|
|
21
|
+
"This skill never edits Todos stores directly. It shells out to the",
|
|
22
|
+
"installed todos CLI only for explicit show commands.",
|
|
23
|
+
].join("\n");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function runTodos(args: string[]): number {
|
|
27
|
+
const result = spawnSync("todos", args, { stdio: "inherit" });
|
|
28
|
+
if (result.error) {
|
|
29
|
+
console.error(`todos CLI unavailable: ${result.error.message}`);
|
|
30
|
+
return 1;
|
|
31
|
+
}
|
|
32
|
+
return typeof result.status === "number" ? result.status : 1;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const [command, ...args] = process.argv.slice(2);
|
|
36
|
+
|
|
37
|
+
if (!command || command === "--help" || command === "-h") {
|
|
38
|
+
console.log(usage());
|
|
39
|
+
process.exit(0);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (command === "checklist") {
|
|
43
|
+
for (const item of CHECKLIST) console.log(`- ${item}`);
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (command === "path") {
|
|
48
|
+
const [projectId, slug] = args;
|
|
49
|
+
if (!projectId || !slug) {
|
|
50
|
+
console.error("Usage: todos-plan path <project-id> <plan-slug>");
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
console.log(`.hasna/todos/plans/${projectId}/${slug}.md`);
|
|
54
|
+
process.exit(0);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (command === "show") {
|
|
58
|
+
const [planId] = args;
|
|
59
|
+
if (!planId) {
|
|
60
|
+
console.error("Usage: todos-plan show <plan-id>");
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
process.exit(runTodos(["plans", "--show", planId]));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
console.error(`Unknown command: ${command}`);
|
|
67
|
+
console.error(usage());
|
|
68
|
+
process.exit(1);
|