opencastle 0.32.13 → 0.33.1
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/LICENSE +21 -93
- package/README.md +1 -1
- package/package.json +2 -2
- package/src/dashboard/dist/data/convoys/demo-api-v2.json +3 -3
- package/src/dashboard/dist/data/convoys/demo-auth-revamp.json +4 -4
- package/src/dashboard/dist/data/convoys/demo-dashboard-ui.json +6 -6
- package/src/dashboard/dist/data/convoys/demo-data-pipeline.json +3 -3
- package/src/dashboard/dist/data/convoys/demo-deploy-ci.json +1 -1
- package/src/dashboard/dist/data/convoys/demo-docs-update.json +3 -3
- package/src/dashboard/dist/data/convoys/demo-perf-opt.json +10 -10
- package/src/dashboard/dist/index.html +21 -25
- package/src/dashboard/node_modules/.vite/deps/_metadata.json +6 -6
- package/src/dashboard/public/data/convoys/demo-api-v2.json +3 -3
- package/src/dashboard/public/data/convoys/demo-auth-revamp.json +4 -4
- package/src/dashboard/public/data/convoys/demo-dashboard-ui.json +6 -6
- package/src/dashboard/public/data/convoys/demo-data-pipeline.json +3 -3
- package/src/dashboard/public/data/convoys/demo-deploy-ci.json +1 -1
- package/src/dashboard/public/data/convoys/demo-docs-update.json +3 -3
- package/src/dashboard/public/data/convoys/demo-perf-opt.json +10 -10
- package/src/dashboard/src/pages/index.astro +21 -25
- package/src/orchestrator/prompts/create-skill.prompt.md +2 -2
- package/src/orchestrator/prompts/generate-convoy.prompt.md +6 -0
- package/src/orchestrator/prompts/generate-prd.prompt.md +4 -0
- package/src/orchestrator/skills/backbone-scaffolding/EXAMPLES.md +16 -0
- package/src/orchestrator/skills/backbone-scaffolding/SKILL.md +99 -0
- package/src/orchestrator/skills/git-workflow/SKILL.md +12 -1
package/LICENSE
CHANGED
|
@@ -1,93 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
please contact Filip Mares.
|
|
23
|
-
|
|
24
|
-
Notice
|
|
25
|
-
|
|
26
|
-
Business Source License 1.1
|
|
27
|
-
|
|
28
|
-
Terms
|
|
29
|
-
|
|
30
|
-
The Licensor hereby grants you the right to copy, modify, create derivative
|
|
31
|
-
works, redistribute, and make non-production use of the Licensed Work. The
|
|
32
|
-
Licensor may make an Additional Use Grant, above, permitting limited production
|
|
33
|
-
use.
|
|
34
|
-
|
|
35
|
-
Effective on the Change Date, or the fourth anniversary of the first publicly
|
|
36
|
-
available distribution of a specific version of the Licensed Work under this
|
|
37
|
-
License, whichever comes first, the Licensor hereby grants you rights under the
|
|
38
|
-
terms of the Change License, and the rights granted in the paragraph above
|
|
39
|
-
terminate.
|
|
40
|
-
|
|
41
|
-
If your use of the Licensed Work does not comply with the requirements currently
|
|
42
|
-
in effect as described in this License, you must purchase a commercial license
|
|
43
|
-
from the Licensor, its affiliated entities, or authorized resellers, or you must
|
|
44
|
-
refrain from using the Licensed Work.
|
|
45
|
-
|
|
46
|
-
All copies of the original and modified Licensed Work, and derivative works of
|
|
47
|
-
the Licensed Work, are subject to this License. This License applies separately
|
|
48
|
-
for each version of the Licensed Work and the Change Date may vary for each
|
|
49
|
-
version of the Licensed Work released by Licensor.
|
|
50
|
-
|
|
51
|
-
You must conspicuously display this License on each original or modified copy of
|
|
52
|
-
the Licensed Work. If you receive the Licensed Work in original or modified form
|
|
53
|
-
from a third party, the terms and conditions set forth in this License apply to
|
|
54
|
-
your use of that work.
|
|
55
|
-
|
|
56
|
-
Any use of the Licensed Work in violation of this License will automatically
|
|
57
|
-
terminate your rights under this License for the current and all other versions
|
|
58
|
-
of the Licensed Work.
|
|
59
|
-
|
|
60
|
-
This License does not grant you any right in any trademark or logo of Licensor
|
|
61
|
-
or its affiliates (provided that you may use a trademark or logo of Licensor as
|
|
62
|
-
expressly required by this License).
|
|
63
|
-
|
|
64
|
-
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON AN
|
|
65
|
-
"AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
|
|
66
|
-
OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
|
|
67
|
-
FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
|
|
68
|
-
|
|
69
|
-
MariaDB hereby grants you permission to use this License's text to license your
|
|
70
|
-
works, and to refer to it using the trademark "Business Source License", as long
|
|
71
|
-
as you comply with the Covenants of Licensor below.
|
|
72
|
-
|
|
73
|
-
Covenants of Licensor
|
|
74
|
-
|
|
75
|
-
In consideration of the right to use this License's text and the "Business
|
|
76
|
-
Source License" name and trademark, Licensor covenants to MariaDB, and to all
|
|
77
|
-
other recipients of the licensed work to be provided by Licensor:
|
|
78
|
-
|
|
79
|
-
1. To specify as the Change License the GPL Version 2.0 or any later version,
|
|
80
|
-
or a license that is compatible with GPL Version 2.0 or a later version,
|
|
81
|
-
where "compatible" means that software provided under the Change License can
|
|
82
|
-
be included in a program with software provided under GPL Version 2.0 or a
|
|
83
|
-
later version. Licensor may specify additional Change Licenses without
|
|
84
|
-
limitation.
|
|
85
|
-
|
|
86
|
-
2. To either: (a) specify an additional grant of rights to use that does not
|
|
87
|
-
impose any additional condition, limitation, or restriction on the right
|
|
88
|
-
granted in this License, as the Additional Use Grant; or (b) insert the text
|
|
89
|
-
"None".
|
|
90
|
-
|
|
91
|
-
3. To specify a Change Date.
|
|
92
|
-
|
|
93
|
-
4. Not to modify this License in any other way.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Filip Mares
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -109,7 +109,7 @@ Add `--dry-run` to any command to preview what it would change without writing f
|
|
|
109
109
|
|
|
110
110
|
**Specialist Agents.** Developer, UI/UX, Database, Security, Testing, Reviewer, and more.
|
|
111
111
|
|
|
112
|
-
**On-Demand Skills.** Loaded on demand to keep context windows lean. Auto-selected during init based on your stack. All 51 skills and plugins scored 100% on the [tessl Skill Evaluator](https://tessl.io/registry
|
|
112
|
+
**On-Demand Skills.** Loaded on demand to keep context windows lean. Auto-selected during init based on your stack. All 51 skills and plugins scored 100% on the [tessl Skill Evaluator](https://tessl.io/registry?q=opencastle).
|
|
113
113
|
|
|
114
114
|
**Workflow Templates.** Features, bug fixes, data pipelines, security audits — reproducible execution templates.
|
|
115
115
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencastle",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Multi-agent orchestration framework for AI coding assistants",
|
|
6
6
|
"bin": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"url": "https://github.com/monkilabs/opencastle/issues"
|
|
32
32
|
},
|
|
33
33
|
"homepage": "https://www.opencastle.dev/",
|
|
34
|
-
"license": "
|
|
34
|
+
"license": "MIT",
|
|
35
35
|
"author": "Filip Mares",
|
|
36
36
|
"scripts": {
|
|
37
37
|
"build": "npm run cli:build && npm run dashboard:build",
|
|
@@ -51,21 +51,21 @@
|
|
|
51
51
|
"name": "docs/api-v2-contract.json",
|
|
52
52
|
"type": "json",
|
|
53
53
|
"task_id": "api-t1",
|
|
54
|
-
"created_at": "2026-04-
|
|
54
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"id": "artifact-demo-api-v2-reports-security-gate-failure-md",
|
|
58
58
|
"name": "reports/security-gate-failure.md",
|
|
59
59
|
"type": "summary",
|
|
60
60
|
"task_id": "api-t3",
|
|
61
|
-
"created_at": "2026-04-
|
|
61
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
"id": "artifact-demo-api-v2-src-api-rate-limiter-ts",
|
|
65
65
|
"name": "src/api/rate-limiter.ts",
|
|
66
66
|
"type": "file",
|
|
67
67
|
"task_id": "api-t2",
|
|
68
|
-
"created_at": "2026-04-
|
|
68
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
69
69
|
}
|
|
70
70
|
],
|
|
71
71
|
"has_more_events": false,
|
|
@@ -42,28 +42,28 @@
|
|
|
42
42
|
"name": "libs/auth/src/jwt-middleware.ts",
|
|
43
43
|
"type": "file",
|
|
44
44
|
"task_id": "auth-t2",
|
|
45
|
-
"created_at": "2026-04-
|
|
45
|
+
"created_at": "2026-04-05T06:40:02.268Z"
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
"id": "artifact-demo-auth-revamp-libs-auth-src-rls-policies-sql",
|
|
49
49
|
"name": "libs/auth/src/rls-policies.sql",
|
|
50
50
|
"type": "file",
|
|
51
51
|
"task_id": "auth-t3",
|
|
52
|
-
"created_at": "2026-04-
|
|
52
|
+
"created_at": "2026-04-05T06:40:02.268Z"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
"id": "artifact-demo-auth-revamp-reports-auth-review-summary-md",
|
|
56
56
|
"name": "reports/auth-review-summary.md",
|
|
57
57
|
"type": "summary",
|
|
58
58
|
"task_id": "auth-t5",
|
|
59
|
-
"created_at": "2026-04-
|
|
59
|
+
"created_at": "2026-04-05T06:40:02.268Z"
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
"id": "artifact-demo-auth-revamp-tests-auth-integration-test-ts",
|
|
63
63
|
"name": "tests/auth/integration.test.ts",
|
|
64
64
|
"type": "file",
|
|
65
65
|
"task_id": "auth-t4",
|
|
66
|
-
"created_at": "2026-04-
|
|
66
|
+
"created_at": "2026-04-05T06:40:02.268Z"
|
|
67
67
|
}
|
|
68
68
|
],
|
|
69
69
|
"has_more_events": false,
|
|
@@ -51,42 +51,42 @@
|
|
|
51
51
|
"name": "reports/panel-review-dashboard.md",
|
|
52
52
|
"type": "summary",
|
|
53
53
|
"task_id": "ui-t7",
|
|
54
|
-
"created_at": "2026-04-
|
|
54
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"id": "artifact-demo-dashboard-ui-reports-visual-regression-json",
|
|
58
58
|
"name": "reports/visual-regression.json",
|
|
59
59
|
"type": "json",
|
|
60
60
|
"task_id": "ui-t6",
|
|
61
|
-
"created_at": "2026-04-
|
|
61
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
"id": "artifact-demo-dashboard-ui-src-components-DonutChart-tsx",
|
|
65
65
|
"name": "src/components/DonutChart.tsx",
|
|
66
66
|
"type": "file",
|
|
67
67
|
"task_id": "ui-t3",
|
|
68
|
-
"created_at": "2026-04-
|
|
68
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
69
69
|
},
|
|
70
70
|
{
|
|
71
71
|
"id": "artifact-demo-dashboard-ui-src-components-KpiCard-tsx",
|
|
72
72
|
"name": "src/components/KpiCard.tsx",
|
|
73
73
|
"type": "file",
|
|
74
74
|
"task_id": "ui-t2",
|
|
75
|
-
"created_at": "2026-04-
|
|
75
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
78
|
"id": "artifact-demo-dashboard-ui-src-components-design-tokens-ts",
|
|
79
79
|
"name": "src/components/design-tokens.ts",
|
|
80
80
|
"type": "file",
|
|
81
81
|
"task_id": "ui-t1",
|
|
82
|
-
"created_at": "2026-04-
|
|
82
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
83
83
|
},
|
|
84
84
|
{
|
|
85
85
|
"id": "artifact-demo-dashboard-ui-src-styles-animations-css",
|
|
86
86
|
"name": "src/styles/animations.css",
|
|
87
87
|
"type": "file",
|
|
88
88
|
"task_id": "ui-t4",
|
|
89
|
-
"created_at": "2026-04-
|
|
89
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
90
90
|
}
|
|
91
91
|
],
|
|
92
92
|
"has_more_events": false,
|
|
@@ -42,21 +42,21 @@
|
|
|
42
42
|
"name": "src/etl/pipeline.ts",
|
|
43
43
|
"type": "file",
|
|
44
44
|
"task_id": "etl-t2",
|
|
45
|
-
"created_at": "2026-04-
|
|
45
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
"id": "artifact-demo-data-pipeline-src-etl-schema-ts",
|
|
49
49
|
"name": "src/etl/schema.ts",
|
|
50
50
|
"type": "file",
|
|
51
51
|
"task_id": "etl-t1",
|
|
52
|
-
"created_at": "2026-04-
|
|
52
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
"id": "artifact-demo-data-pipeline-tests-etl-pipeline-test-ts",
|
|
56
56
|
"name": "tests/etl/pipeline.test.ts",
|
|
57
57
|
"type": "file",
|
|
58
58
|
"task_id": "etl-t3",
|
|
59
|
-
"created_at": "2026-04-
|
|
59
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
60
60
|
}
|
|
61
61
|
],
|
|
62
62
|
"has_more_events": false,
|
|
@@ -42,21 +42,21 @@
|
|
|
42
42
|
"name": "docs/ARCHITECTURE.md",
|
|
43
43
|
"type": "file",
|
|
44
44
|
"task_id": "docs-t1",
|
|
45
|
-
"created_at": "2026-04-
|
|
45
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
"id": "artifact-demo-docs-update-docs-README-md",
|
|
49
49
|
"name": "docs/README.md",
|
|
50
50
|
"type": "file",
|
|
51
51
|
"task_id": "docs-t1",
|
|
52
|
-
"created_at": "2026-04-
|
|
52
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
"id": "artifact-demo-docs-update-docs-api-reference-json",
|
|
56
56
|
"name": "docs/api-reference.json",
|
|
57
57
|
"type": "json",
|
|
58
58
|
"task_id": "docs-t2",
|
|
59
|
-
"created_at": "2026-04-
|
|
59
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
60
60
|
}
|
|
61
61
|
],
|
|
62
62
|
"has_more_events": false,
|
|
@@ -42,28 +42,28 @@
|
|
|
42
42
|
"name": "reports/bundle-analysis.json",
|
|
43
43
|
"type": "json",
|
|
44
44
|
"task_id": "perf-t1",
|
|
45
|
-
"created_at": "2026-04-
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
"id": "artifact-demo-perf-opt-reports-web-vitals-improvement-md",
|
|
49
|
-
"name": "reports/web-vitals-improvement.md",
|
|
50
|
-
"type": "summary",
|
|
51
|
-
"task_id": "perf-t4",
|
|
52
|
-
"created_at": "2026-04-02T08:27:08.548Z"
|
|
45
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
53
46
|
},
|
|
54
47
|
{
|
|
55
48
|
"id": "artifact-demo-perf-opt-src-charts-index-ts",
|
|
56
49
|
"name": "src/charts/index.ts",
|
|
57
50
|
"type": "file",
|
|
58
51
|
"task_id": "perf-t2",
|
|
59
|
-
"created_at": "2026-04-
|
|
52
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"id": "artifact-demo-perf-opt-reports-web-vitals-improvement-md",
|
|
56
|
+
"name": "reports/web-vitals-improvement.md",
|
|
57
|
+
"type": "summary",
|
|
58
|
+
"task_id": "perf-t4",
|
|
59
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
"id": "artifact-demo-perf-opt-src-utils-image-loader-ts",
|
|
63
63
|
"name": "src/utils/image-loader.ts",
|
|
64
64
|
"type": "file",
|
|
65
65
|
"task_id": "perf-t3",
|
|
66
|
-
"created_at": "2026-04-
|
|
66
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
67
67
|
}
|
|
68
68
|
],
|
|
69
69
|
"has_more_events": false,
|
|
@@ -97,6 +97,7 @@ Export
|
|
|
97
97
|
// ── Active Convoy Polling ──────────────────────────────────
|
|
98
98
|
let _activePollingTimer = null;
|
|
99
99
|
let _activePollingConvoyId = null;
|
|
100
|
+
let _lastPolledConvoyStatus = null;
|
|
100
101
|
|
|
101
102
|
function startActiveConvoyPolling() {
|
|
102
103
|
if (_activePollingTimer) return; // already polling
|
|
@@ -126,6 +127,7 @@ Export
|
|
|
126
127
|
// If we haven't navigated to any convoy yet, navigate now
|
|
127
128
|
if (!_activePollingConvoyId) {
|
|
128
129
|
_activePollingConvoyId = convoy.id;
|
|
130
|
+
_lastPolledConvoyStatus = null;
|
|
129
131
|
// Refresh ETL data so convoy detail JSON exists
|
|
130
132
|
await fetch(base + 'data/refresh');
|
|
131
133
|
// Re-fetch the convoy list and stats
|
|
@@ -137,36 +139,32 @@ Export
|
|
|
137
139
|
// If we're on a convoy and a new one started (pipeline chain), follow it
|
|
138
140
|
if (_activePollingConvoyId !== convoy.id && isRunningOrPending) {
|
|
139
141
|
_activePollingConvoyId = convoy.id;
|
|
142
|
+
_lastPolledConvoyStatus = null;
|
|
140
143
|
await fetch(base + 'data/refresh');
|
|
141
144
|
await refreshDashboardData();
|
|
142
145
|
showConvoyDetailView(convoy.id, convoy.name || convoy.id);
|
|
143
146
|
}
|
|
144
147
|
|
|
145
|
-
// If we're viewing the active convoy, refresh
|
|
148
|
+
// If we're viewing the active convoy, refresh when it's running or just transitioned
|
|
146
149
|
if (_activePollingConvoyId === convoy.id) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
if (!isRunningOrPending) {
|
|
160
|
-
// In pipeline mode, check if all convoys in the chain are done
|
|
161
|
-
if (data.pipeline) {
|
|
162
|
-
const anyActive = data.pipeline.some(c => c.status === 'running' || c.status === 'pending');
|
|
163
|
-
if (!anyActive) {
|
|
164
|
-
stopActiveConvoyPolling();
|
|
150
|
+
const statusChanged = _lastPolledConvoyStatus !== null && _lastPolledConvoyStatus !== convoy.status;
|
|
151
|
+
_lastPolledConvoyStatus = convoy.status;
|
|
152
|
+
|
|
153
|
+
if (isRunningOrPending || statusChanged) {
|
|
154
|
+
await fetch(base + 'data/refresh');
|
|
155
|
+
await refreshDashboardData();
|
|
156
|
+
// Reload convoy detail to show latest task progress
|
|
157
|
+
await loadConvoyDetail(convoy.id);
|
|
158
|
+
|
|
159
|
+
// Update pipeline chain breadcrumb if applicable
|
|
160
|
+
if (data.pipeline && data.pipeline.length > 1) {
|
|
161
|
+
renderPipelineChain(data.pipeline, convoy.id);
|
|
165
162
|
}
|
|
166
|
-
} else {
|
|
167
|
-
stopActiveConvoyPolling();
|
|
168
163
|
}
|
|
169
164
|
}
|
|
165
|
+
|
|
166
|
+
// NOTE: In 'active' mode we intentionally keep polling even after a convoy finishes,
|
|
167
|
+
// so that subsequent convoys are detected when they start.
|
|
170
168
|
} catch {
|
|
171
169
|
// Polling errors are non-fatal — just retry next interval
|
|
172
170
|
}
|
|
@@ -1817,11 +1815,9 @@ Export
|
|
|
1817
1815
|
const target = running || latest;
|
|
1818
1816
|
if (target) {
|
|
1819
1817
|
_activePollingConvoyId = target.id;
|
|
1818
|
+
_lastPolledConvoyStatus = null;
|
|
1820
1819
|
showConvoyDetailView(target.id, target.name || target.id);
|
|
1821
|
-
|
|
1822
|
-
if (target.status === 'running' || target.status === 'pending') {
|
|
1823
|
-
startActiveConvoyPolling();
|
|
1824
|
-
}
|
|
1820
|
+
startActiveConvoyPolling();
|
|
1825
1821
|
} else {
|
|
1826
1822
|
// No convoy exists yet — show waiting state and poll
|
|
1827
1823
|
showWaitingBanner();
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
{
|
|
2
|
-
"hash": "
|
|
2
|
+
"hash": "d345d9ae",
|
|
3
3
|
"configHash": "30f8ea04",
|
|
4
|
-
"lockfileHash": "
|
|
5
|
-
"browserHash": "
|
|
4
|
+
"lockfileHash": "ea94e1c1",
|
|
5
|
+
"browserHash": "c13f12ac",
|
|
6
6
|
"optimized": {
|
|
7
7
|
"astro > cssesc": {
|
|
8
8
|
"src": "../../../../../node_modules/cssesc/cssesc.js",
|
|
9
9
|
"file": "astro___cssesc.js",
|
|
10
|
-
"fileHash": "
|
|
10
|
+
"fileHash": "1d552a66",
|
|
11
11
|
"needsInterop": true
|
|
12
12
|
},
|
|
13
13
|
"astro > aria-query": {
|
|
14
14
|
"src": "../../../../../node_modules/aria-query/lib/index.js",
|
|
15
15
|
"file": "astro___aria-query.js",
|
|
16
|
-
"fileHash": "
|
|
16
|
+
"fileHash": "6c55b8e9",
|
|
17
17
|
"needsInterop": true
|
|
18
18
|
},
|
|
19
19
|
"astro > axobject-query": {
|
|
20
20
|
"src": "../../../../../node_modules/axobject-query/lib/index.js",
|
|
21
21
|
"file": "astro___axobject-query.js",
|
|
22
|
-
"fileHash": "
|
|
22
|
+
"fileHash": "a912fe24",
|
|
23
23
|
"needsInterop": true
|
|
24
24
|
}
|
|
25
25
|
},
|
|
@@ -51,21 +51,21 @@
|
|
|
51
51
|
"name": "docs/api-v2-contract.json",
|
|
52
52
|
"type": "json",
|
|
53
53
|
"task_id": "api-t1",
|
|
54
|
-
"created_at": "2026-04-
|
|
54
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"id": "artifact-demo-api-v2-reports-security-gate-failure-md",
|
|
58
58
|
"name": "reports/security-gate-failure.md",
|
|
59
59
|
"type": "summary",
|
|
60
60
|
"task_id": "api-t3",
|
|
61
|
-
"created_at": "2026-04-
|
|
61
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
"id": "artifact-demo-api-v2-src-api-rate-limiter-ts",
|
|
65
65
|
"name": "src/api/rate-limiter.ts",
|
|
66
66
|
"type": "file",
|
|
67
67
|
"task_id": "api-t2",
|
|
68
|
-
"created_at": "2026-04-
|
|
68
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
69
69
|
}
|
|
70
70
|
],
|
|
71
71
|
"has_more_events": false,
|
|
@@ -42,28 +42,28 @@
|
|
|
42
42
|
"name": "libs/auth/src/jwt-middleware.ts",
|
|
43
43
|
"type": "file",
|
|
44
44
|
"task_id": "auth-t2",
|
|
45
|
-
"created_at": "2026-04-
|
|
45
|
+
"created_at": "2026-04-05T06:40:02.268Z"
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
"id": "artifact-demo-auth-revamp-libs-auth-src-rls-policies-sql",
|
|
49
49
|
"name": "libs/auth/src/rls-policies.sql",
|
|
50
50
|
"type": "file",
|
|
51
51
|
"task_id": "auth-t3",
|
|
52
|
-
"created_at": "2026-04-
|
|
52
|
+
"created_at": "2026-04-05T06:40:02.268Z"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
"id": "artifact-demo-auth-revamp-reports-auth-review-summary-md",
|
|
56
56
|
"name": "reports/auth-review-summary.md",
|
|
57
57
|
"type": "summary",
|
|
58
58
|
"task_id": "auth-t5",
|
|
59
|
-
"created_at": "2026-04-
|
|
59
|
+
"created_at": "2026-04-05T06:40:02.268Z"
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
"id": "artifact-demo-auth-revamp-tests-auth-integration-test-ts",
|
|
63
63
|
"name": "tests/auth/integration.test.ts",
|
|
64
64
|
"type": "file",
|
|
65
65
|
"task_id": "auth-t4",
|
|
66
|
-
"created_at": "2026-04-
|
|
66
|
+
"created_at": "2026-04-05T06:40:02.268Z"
|
|
67
67
|
}
|
|
68
68
|
],
|
|
69
69
|
"has_more_events": false,
|
|
@@ -51,42 +51,42 @@
|
|
|
51
51
|
"name": "reports/panel-review-dashboard.md",
|
|
52
52
|
"type": "summary",
|
|
53
53
|
"task_id": "ui-t7",
|
|
54
|
-
"created_at": "2026-04-
|
|
54
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"id": "artifact-demo-dashboard-ui-reports-visual-regression-json",
|
|
58
58
|
"name": "reports/visual-regression.json",
|
|
59
59
|
"type": "json",
|
|
60
60
|
"task_id": "ui-t6",
|
|
61
|
-
"created_at": "2026-04-
|
|
61
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
"id": "artifact-demo-dashboard-ui-src-components-DonutChart-tsx",
|
|
65
65
|
"name": "src/components/DonutChart.tsx",
|
|
66
66
|
"type": "file",
|
|
67
67
|
"task_id": "ui-t3",
|
|
68
|
-
"created_at": "2026-04-
|
|
68
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
69
69
|
},
|
|
70
70
|
{
|
|
71
71
|
"id": "artifact-demo-dashboard-ui-src-components-KpiCard-tsx",
|
|
72
72
|
"name": "src/components/KpiCard.tsx",
|
|
73
73
|
"type": "file",
|
|
74
74
|
"task_id": "ui-t2",
|
|
75
|
-
"created_at": "2026-04-
|
|
75
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
78
|
"id": "artifact-demo-dashboard-ui-src-components-design-tokens-ts",
|
|
79
79
|
"name": "src/components/design-tokens.ts",
|
|
80
80
|
"type": "file",
|
|
81
81
|
"task_id": "ui-t1",
|
|
82
|
-
"created_at": "2026-04-
|
|
82
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
83
83
|
},
|
|
84
84
|
{
|
|
85
85
|
"id": "artifact-demo-dashboard-ui-src-styles-animations-css",
|
|
86
86
|
"name": "src/styles/animations.css",
|
|
87
87
|
"type": "file",
|
|
88
88
|
"task_id": "ui-t4",
|
|
89
|
-
"created_at": "2026-04-
|
|
89
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
90
90
|
}
|
|
91
91
|
],
|
|
92
92
|
"has_more_events": false,
|
|
@@ -42,21 +42,21 @@
|
|
|
42
42
|
"name": "src/etl/pipeline.ts",
|
|
43
43
|
"type": "file",
|
|
44
44
|
"task_id": "etl-t2",
|
|
45
|
-
"created_at": "2026-04-
|
|
45
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
"id": "artifact-demo-data-pipeline-src-etl-schema-ts",
|
|
49
49
|
"name": "src/etl/schema.ts",
|
|
50
50
|
"type": "file",
|
|
51
51
|
"task_id": "etl-t1",
|
|
52
|
-
"created_at": "2026-04-
|
|
52
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
"id": "artifact-demo-data-pipeline-tests-etl-pipeline-test-ts",
|
|
56
56
|
"name": "tests/etl/pipeline.test.ts",
|
|
57
57
|
"type": "file",
|
|
58
58
|
"task_id": "etl-t3",
|
|
59
|
-
"created_at": "2026-04-
|
|
59
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
60
60
|
}
|
|
61
61
|
],
|
|
62
62
|
"has_more_events": false,
|
|
@@ -42,21 +42,21 @@
|
|
|
42
42
|
"name": "docs/ARCHITECTURE.md",
|
|
43
43
|
"type": "file",
|
|
44
44
|
"task_id": "docs-t1",
|
|
45
|
-
"created_at": "2026-04-
|
|
45
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
"id": "artifact-demo-docs-update-docs-README-md",
|
|
49
49
|
"name": "docs/README.md",
|
|
50
50
|
"type": "file",
|
|
51
51
|
"task_id": "docs-t1",
|
|
52
|
-
"created_at": "2026-04-
|
|
52
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
"id": "artifact-demo-docs-update-docs-api-reference-json",
|
|
56
56
|
"name": "docs/api-reference.json",
|
|
57
57
|
"type": "json",
|
|
58
58
|
"task_id": "docs-t2",
|
|
59
|
-
"created_at": "2026-04-
|
|
59
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
60
60
|
}
|
|
61
61
|
],
|
|
62
62
|
"has_more_events": false,
|
|
@@ -42,28 +42,28 @@
|
|
|
42
42
|
"name": "reports/bundle-analysis.json",
|
|
43
43
|
"type": "json",
|
|
44
44
|
"task_id": "perf-t1",
|
|
45
|
-
"created_at": "2026-04-
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
"id": "artifact-demo-perf-opt-reports-web-vitals-improvement-md",
|
|
49
|
-
"name": "reports/web-vitals-improvement.md",
|
|
50
|
-
"type": "summary",
|
|
51
|
-
"task_id": "perf-t4",
|
|
52
|
-
"created_at": "2026-04-02T08:27:08.548Z"
|
|
45
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
53
46
|
},
|
|
54
47
|
{
|
|
55
48
|
"id": "artifact-demo-perf-opt-src-charts-index-ts",
|
|
56
49
|
"name": "src/charts/index.ts",
|
|
57
50
|
"type": "file",
|
|
58
51
|
"task_id": "perf-t2",
|
|
59
|
-
"created_at": "2026-04-
|
|
52
|
+
"created_at": "2026-04-05T06:40:02.269Z"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"id": "artifact-demo-perf-opt-reports-web-vitals-improvement-md",
|
|
56
|
+
"name": "reports/web-vitals-improvement.md",
|
|
57
|
+
"type": "summary",
|
|
58
|
+
"task_id": "perf-t4",
|
|
59
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
"id": "artifact-demo-perf-opt-src-utils-image-loader-ts",
|
|
63
63
|
"name": "src/utils/image-loader.ts",
|
|
64
64
|
"type": "file",
|
|
65
65
|
"task_id": "perf-t3",
|
|
66
|
-
"created_at": "2026-04-
|
|
66
|
+
"created_at": "2026-04-05T06:40:02.270Z"
|
|
67
67
|
}
|
|
68
68
|
],
|
|
69
69
|
"has_more_events": false,
|
|
@@ -447,6 +447,7 @@ try {
|
|
|
447
447
|
// ── Active Convoy Polling ──────────────────────────────────
|
|
448
448
|
let _activePollingTimer = null;
|
|
449
449
|
let _activePollingConvoyId = null;
|
|
450
|
+
let _lastPolledConvoyStatus = null;
|
|
450
451
|
|
|
451
452
|
function startActiveConvoyPolling() {
|
|
452
453
|
if (_activePollingTimer) return; // already polling
|
|
@@ -476,6 +477,7 @@ try {
|
|
|
476
477
|
// If we haven't navigated to any convoy yet, navigate now
|
|
477
478
|
if (!_activePollingConvoyId) {
|
|
478
479
|
_activePollingConvoyId = convoy.id;
|
|
480
|
+
_lastPolledConvoyStatus = null;
|
|
479
481
|
// Refresh ETL data so convoy detail JSON exists
|
|
480
482
|
await fetch(base + 'data/refresh');
|
|
481
483
|
// Re-fetch the convoy list and stats
|
|
@@ -487,36 +489,32 @@ try {
|
|
|
487
489
|
// If we're on a convoy and a new one started (pipeline chain), follow it
|
|
488
490
|
if (_activePollingConvoyId !== convoy.id && isRunningOrPending) {
|
|
489
491
|
_activePollingConvoyId = convoy.id;
|
|
492
|
+
_lastPolledConvoyStatus = null;
|
|
490
493
|
await fetch(base + 'data/refresh');
|
|
491
494
|
await refreshDashboardData();
|
|
492
495
|
showConvoyDetailView(convoy.id, convoy.name || convoy.id);
|
|
493
496
|
}
|
|
494
497
|
|
|
495
|
-
// If we're viewing the active convoy, refresh
|
|
498
|
+
// If we're viewing the active convoy, refresh when it's running or just transitioned
|
|
496
499
|
if (_activePollingConvoyId === convoy.id) {
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
if (!isRunningOrPending) {
|
|
510
|
-
// In pipeline mode, check if all convoys in the chain are done
|
|
511
|
-
if (data.pipeline) {
|
|
512
|
-
const anyActive = data.pipeline.some(c => c.status === 'running' || c.status === 'pending');
|
|
513
|
-
if (!anyActive) {
|
|
514
|
-
stopActiveConvoyPolling();
|
|
500
|
+
const statusChanged = _lastPolledConvoyStatus !== null && _lastPolledConvoyStatus !== convoy.status;
|
|
501
|
+
_lastPolledConvoyStatus = convoy.status;
|
|
502
|
+
|
|
503
|
+
if (isRunningOrPending || statusChanged) {
|
|
504
|
+
await fetch(base + 'data/refresh');
|
|
505
|
+
await refreshDashboardData();
|
|
506
|
+
// Reload convoy detail to show latest task progress
|
|
507
|
+
await loadConvoyDetail(convoy.id);
|
|
508
|
+
|
|
509
|
+
// Update pipeline chain breadcrumb if applicable
|
|
510
|
+
if (data.pipeline && data.pipeline.length > 1) {
|
|
511
|
+
renderPipelineChain(data.pipeline, convoy.id);
|
|
515
512
|
}
|
|
516
|
-
} else {
|
|
517
|
-
stopActiveConvoyPolling();
|
|
518
513
|
}
|
|
519
514
|
}
|
|
515
|
+
|
|
516
|
+
// NOTE: In 'active' mode we intentionally keep polling even after a convoy finishes,
|
|
517
|
+
// so that subsequent convoys are detected when they start.
|
|
520
518
|
} catch {
|
|
521
519
|
// Polling errors are non-fatal — just retry next interval
|
|
522
520
|
}
|
|
@@ -2167,11 +2165,9 @@ try {
|
|
|
2167
2165
|
const target = running || latest;
|
|
2168
2166
|
if (target) {
|
|
2169
2167
|
_activePollingConvoyId = target.id;
|
|
2168
|
+
_lastPolledConvoyStatus = null;
|
|
2170
2169
|
showConvoyDetailView(target.id, target.name || target.id);
|
|
2171
|
-
|
|
2172
|
-
if (target.status === 'running' || target.status === 'pending') {
|
|
2173
|
-
startActiveConvoyPolling();
|
|
2174
|
-
}
|
|
2170
|
+
startActiveConvoyPolling();
|
|
2175
2171
|
} else {
|
|
2176
2172
|
// No convoy exists yet — show waiting state and poll
|
|
2177
2173
|
showWaitingBanner();
|
|
@@ -123,11 +123,11 @@ Registration differs by type:
|
|
|
123
123
|
- [ ] Skill matrix updated (`directSkills` array or capability slot binding)
|
|
124
124
|
- [ ] For process skills: at least one agent's `directSkills` array includes it in skill-matrix.json
|
|
125
125
|
- [ ] For plugin skills: `config.ts` `skillName` matches the `name` in frontmatter
|
|
126
|
-
- [ ] Run `npx tessl skill review <path>` — target 100
|
|
126
|
+
- [ ] Run `npx tessl skill review <path>` — target 100 score (see Scoring Criteria below)
|
|
127
127
|
|
|
128
128
|
## Scoring Criteria
|
|
129
129
|
|
|
130
|
-
Skills are evaluated by `npx tessl skill review` across 8 criteria (3 pts each = 24 total). Target 100
|
|
130
|
+
Skills are evaluated by `npx tessl skill review` across 8 criteria (3 pts each = 24 total). Target 100.
|
|
131
131
|
|
|
132
132
|
### Description (frontmatter `description` field)
|
|
133
133
|
|
|
@@ -75,6 +75,12 @@ Example prompt suffix to include when content research is needed:
|
|
|
75
75
|
|
|
76
76
|
---
|
|
77
77
|
|
|
78
|
+
### Scaffolding Rule
|
|
79
|
+
|
|
80
|
+
New project from scratch? You MUST load the **backbone-scaffolding** skill and follow it.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
78
84
|
## Workflow
|
|
79
85
|
|
|
80
86
|
### 1. Analyse the Goal
|
|
@@ -31,6 +31,10 @@ If the feature request involves a specific person, place, organization, topic, o
|
|
|
31
31
|
> ℹ️ Content based on training data — verify before launch.
|
|
32
32
|
3. **Never fabricate or hallucinate content.** If you genuinely have no knowledge about a real-world subject and cannot search, state what is unknown and use placeholder text. This applies to all content: bios, descriptions, histories, statistics, quotes, and any factual claims.
|
|
33
33
|
|
|
34
|
+
## Scaffolding Awareness
|
|
35
|
+
|
|
36
|
+
New project from scratch? You MUST load the **backbone-scaffolding** skill and follow it.
|
|
37
|
+
|
|
34
38
|
## Output Rules
|
|
35
39
|
|
|
36
40
|
**CRITICAL:** Return the PRD as your text response. Do NOT create any files. Do NOT use file-writing tools. Simply output the full PRD document as text. Do not wrap it in a code fence — start directly with the `#` heading. Do not summarize — output the complete document.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# backbone-scaffolding Examples
|
|
2
|
+
|
|
3
|
+
## Convoy Scaffolding Task
|
|
4
|
+
|
|
5
|
+
```json
|
|
6
|
+
{
|
|
7
|
+
"id": "scaffolding",
|
|
8
|
+
"description": "Scaffold monorepo with backbone CLI",
|
|
9
|
+
"agent": "developer",
|
|
10
|
+
"complexity": 2,
|
|
11
|
+
"prompt": "Scaffold the project monorepo using the backbone CLI. Ensure Node.js >= 22.5.0 is available. Run: `npx @monkilabs/backbone my-project` and select the following options when prompted:\n- Monorepo: Turborepo\n- Framework: Next.js\n- Backend: Supabase\n- CMS: Sanity\n- Testing: Playwright\n- Deployment: Vercel\n- Mobile: None\n- Packages: Email Library, LLM Library\n\nAfter scaffolding completes, run `npm install` in the generated `my-project/` directory. Then run `npx turbo build` and verify it exits 0.",
|
|
12
|
+
"files": ["my-project/"]
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
All subsequent tasks should declare `depends_on: ["scaffolding"]` and build on the generated structure.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: backbone-scaffolding
|
|
3
|
+
description: "Scaffolds production-ready monorepo projects using the backbone CLI: configures workspace packages, wires build tooling, sets up CI pipelines, and initializes framework/backend/CMS integrations. Use when creating, bootstrapping, or initializing a new application, project, starter template, or monorepo from scratch. Trigger terms: scaffold, bootstrap, init, new repo, new app, boilerplate, starter, greenfield."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# backbone-scaffolding Skill
|
|
7
|
+
|
|
8
|
+
## Requirements
|
|
9
|
+
|
|
10
|
+
- Node.js **>= 22.5.0** must be available in the environment
|
|
11
|
+
- Run backbone with `npx @monkilabs/backbone <project-name>`
|
|
12
|
+
|
|
13
|
+
## How to Use the CLI
|
|
14
|
+
|
|
15
|
+
Backbone is **interactive** — it uses `@clack/prompts` to ask a series of questions. Agents must run the command and respond to each prompt in sequence.
|
|
16
|
+
|
|
17
|
+
### Prompt Sequence
|
|
18
|
+
|
|
19
|
+
1. **Monorepo tool** — `nx` or `turborepo`
|
|
20
|
+
2. **Framework** — `nextjs` or `astro`
|
|
21
|
+
3. **Backend** — `convex`, `supabase`, `prisma`, or `none`
|
|
22
|
+
4. **CMS** — `sanity`, `contentful`, `strapi`, or `none`
|
|
23
|
+
5. **E2E Testing** — `playwright` or `cypress`
|
|
24
|
+
6. **Deployment** — `vercel`, `netlify`, or `none`
|
|
25
|
+
7. **Mobile** — `ionic` or `none` *(only shown for non-Astro frameworks)*
|
|
26
|
+
8. **Packages** — multi-select: `uiLib`, `emailLib`, `llmLib`
|
|
27
|
+
|
|
28
|
+
## CLI Options & Constraints
|
|
29
|
+
|
|
30
|
+
| Category | Choices | Notes |
|
|
31
|
+
|-------------|-------------------------------------------|------------------------------------------|
|
|
32
|
+
| Monorepo | `nx`, `turborepo` | Required |
|
|
33
|
+
| Framework | `nextjs`, `astro` | Required |
|
|
34
|
+
| Backend | `convex`, `supabase`, `prisma` | ⛔ `convex` incompatible with `astro` |
|
|
35
|
+
| CMS | `sanity`, `contentful`, `strapi`, `none` | Optional |
|
|
36
|
+
| E2E Testing | `playwright`, `cypress` | Required |
|
|
37
|
+
| Deployment | `vercel`, `netlify`, `none` | Optional |
|
|
38
|
+
| Mobile | `ionic`, `none` | ⛔ `ionic` incompatible with `astro` |
|
|
39
|
+
| Packages | `uiLib`, `emailLib`, `llmLib` | Multi-select; ⛔ `uiLib` incompatible with `astro` |
|
|
40
|
+
|
|
41
|
+
**Astro constraint:** `astro` requires React-free options — never combine with `convex`, `ionic`, or `uiLib`.
|
|
42
|
+
|
|
43
|
+
## OpenCastle TechTool → Backbone Mapping
|
|
44
|
+
|
|
45
|
+
Most TechTool names map 1:1 to backbone prompt choices (e.g. `nextjs` → select Next.js, `supabase` → select Supabase). Exceptions:
|
|
46
|
+
|
|
47
|
+
| TechTool | Backbone mapping | Notes |
|
|
48
|
+
|----------|-----------------|-------|
|
|
49
|
+
| `resend` | Select `emailLib` in Packages prompt | Only non-obvious mapping |
|
|
50
|
+
| `vitest` | — | Always included automatically |
|
|
51
|
+
| `figma`, `chrome-devtools` | — | Not handled by backbone; configure separately |
|
|
52
|
+
|
|
53
|
+
## Generated Project Structure
|
|
54
|
+
|
|
55
|
+
After backbone runs, the output directory contains:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
<project-name>/
|
|
59
|
+
apps/
|
|
60
|
+
web/ # Next.js or Astro application
|
|
61
|
+
mobile/ # (if ionic selected)
|
|
62
|
+
packages/
|
|
63
|
+
ui/ # (if uiLib selected) shared React component library
|
|
64
|
+
email/ # (if emailLib selected) Resend/React Email package
|
|
65
|
+
llm/ # (if llmLib selected) LLM integration package
|
|
66
|
+
backend/
|
|
67
|
+
convex/ # (if convex selected)
|
|
68
|
+
supabase/ # (if supabase selected)
|
|
69
|
+
e2e/ # Playwright or Cypress tests
|
|
70
|
+
.github/
|
|
71
|
+
workflows/ # GitHub Actions CI pipelines (always included)
|
|
72
|
+
vitest.config.ts # Always included
|
|
73
|
+
tsconfig.base.json # Always included
|
|
74
|
+
package.json # Monorepo root package.json
|
|
75
|
+
turbo.json / nx.json # Monorepo tool config
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Always included regardless of options:** Vitest configuration, GitHub Actions CI workflows, root `tsconfig.base.json`, ESLint, Prettier.
|
|
79
|
+
|
|
80
|
+
Agents working on post-scaffolding tasks must **not recreate** any of these files — they already exist. Build on top of the generated structure.
|
|
81
|
+
|
|
82
|
+
## Post-Scaffolding Steps
|
|
83
|
+
|
|
84
|
+
After `npx @monkilabs/backbone <project-name>` completes:
|
|
85
|
+
|
|
86
|
+
1. `cd <project-name>` into the generated directory
|
|
87
|
+
2. Run `npm install` to install all dependencies
|
|
88
|
+
3. Verify the project builds: run the monorepo build command (e.g. `npx turbo build` or `npx nx build`)
|
|
89
|
+
4. All subsequent agent tasks should **import and extend** the generated boilerplate — never overwrite it
|
|
90
|
+
|
|
91
|
+
**If something fails:**
|
|
92
|
+
- `npm install` errors → verify Node.js >= 22.5.0 (`node -v`)
|
|
93
|
+
- Build errors → check that no incompatible options were selected (see Astro constraint above); re-run backbone with corrected choices if needed
|
|
94
|
+
- Wrong option selected → delete the generated directory and re-run `npx @monkilabs/backbone` with the correct selections
|
|
95
|
+
|
|
96
|
+
## Example Convoy Task
|
|
97
|
+
|
|
98
|
+
See [EXAMPLES.md](EXAMPLES.md) for a complete scaffolding task JSON.
|
|
99
|
+
|
|
@@ -22,7 +22,18 @@ description: "Defines branch naming conventions, PR template requirements, commi
|
|
|
22
22
|
1. Branch `<type>/<ticket-id>-<slug>` from `main`
|
|
23
23
|
2. Atomic commits referencing issue ID
|
|
24
24
|
3. Push branch to origin
|
|
25
|
-
4. Open PR (do NOT merge)
|
|
25
|
+
4. Open PR (do NOT merge) — write the body to a temp file first, then use `--body-file`:
|
|
26
|
+
```sh
|
|
27
|
+
# Write PR body to a temp file to avoid shell escaping issues
|
|
28
|
+
cat > /tmp/pr-body.md << 'EOF'
|
|
29
|
+
Resolves TAS-XX
|
|
30
|
+
|
|
31
|
+
## Changes
|
|
32
|
+
- ...
|
|
33
|
+
EOF
|
|
34
|
+
GH_PAGER=cat gh pr create --base main --title "TAS-XX: Short description" --body-file /tmp/pr-body.md
|
|
35
|
+
```
|
|
36
|
+
**Never use inline `--body` with markdown/backticks/special chars** — it breaks in zsh heredocs and quoted strings.
|
|
26
37
|
5. Update issue with PR URL
|
|
27
38
|
|
|
28
39
|
## Discovered Issues Policy
|