tackle-harness 0.0.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/LICENSE +21 -0
- package/README.en.md +259 -0
- package/README.md +261 -0
- package/bin/tackle.js +150 -0
- package/package.json +29 -0
- package/plugins/contracts/plugin-interface.js +244 -0
- package/plugins/core/hook-skill-gate/index.js +437 -0
- package/plugins/core/hook-skill-gate/plugin.json +12 -0
- package/plugins/core/provider-memory-store/index.js +403 -0
- package/plugins/core/provider-memory-store/plugin.json +9 -0
- package/plugins/core/provider-role-registry/index.js +477 -0
- package/plugins/core/provider-role-registry/plugin.json +9 -0
- package/plugins/core/provider-state-store/index.js +244 -0
- package/plugins/core/provider-state-store/plugin.json +9 -0
- package/plugins/core/skill-agent-dispatcher/plugin.json +13 -0
- package/plugins/core/skill-agent-dispatcher/skill.md +912 -0
- package/plugins/core/skill-batch-task-creator/plugin.json +13 -0
- package/plugins/core/skill-batch-task-creator/skill.md +616 -0
- package/plugins/core/skill-checklist/plugin.json +10 -0
- package/plugins/core/skill-checklist/skill.md +115 -0
- package/plugins/core/skill-completion-report/plugin.json +10 -0
- package/plugins/core/skill-completion-report/skill.md +331 -0
- package/plugins/core/skill-experience-logger/plugin.json +10 -0
- package/plugins/core/skill-experience-logger/skill.md +235 -0
- package/plugins/core/skill-human-checkpoint/plugin.json +10 -0
- package/plugins/core/skill-human-checkpoint/skill.md +194 -0
- package/plugins/core/skill-progress-tracker/plugin.json +10 -0
- package/plugins/core/skill-progress-tracker/skill.md +204 -0
- package/plugins/core/skill-role-manager/plugin.json +10 -0
- package/plugins/core/skill-role-manager/skill.md +252 -0
- package/plugins/core/skill-split-work-package/plugin.json +13 -0
- package/plugins/core/skill-split-work-package/skill.md +446 -0
- package/plugins/core/skill-task-creator/plugin.json +13 -0
- package/plugins/core/skill-task-creator/skill.md +744 -0
- package/plugins/core/skill-team-cleanup/plugin.json +10 -0
- package/plugins/core/skill-team-cleanup/skill.md +266 -0
- package/plugins/core/skill-workflow-orchestrator/plugin.json +13 -0
- package/plugins/core/skill-workflow-orchestrator/skill.md +274 -0
- package/plugins/core/validator-doc-sync/index.js +248 -0
- package/plugins/core/validator-doc-sync/plugin.json +9 -0
- package/plugins/core/validator-work-package/index.js +300 -0
- package/plugins/core/validator-work-package/plugin.json +9 -0
- package/plugins/plugin-registry.json +118 -0
- package/plugins/runtime/config-manager.js +306 -0
- package/plugins/runtime/event-bus.js +187 -0
- package/plugins/runtime/harness-build.js +1019 -0
- package/plugins/runtime/logger.js +174 -0
- package/plugins/runtime/plugin-loader.js +339 -0
- package/plugins/runtime/state-store.js +277 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider: State Store
|
|
3
|
+
*
|
|
4
|
+
* Wraps the StateStore runtime module to provide unified state and task data access.
|
|
5
|
+
* Implements the ProviderPlugin interface from plugin-interface.js.
|
|
6
|
+
*
|
|
7
|
+
* Capabilities:
|
|
8
|
+
* - get(key) read arbitrary state via dot-notation key
|
|
9
|
+
* - getTasks() parse task.md into a structured task list
|
|
10
|
+
* - set(key, value) write state
|
|
11
|
+
* - delete(key) remove a state key
|
|
12
|
+
* - keys() list all stored keys
|
|
13
|
+
* - subscribe(key, cb) watch for changes on a key
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
'use strict';
|
|
17
|
+
|
|
18
|
+
var path = require('path');
|
|
19
|
+
var fs = require('fs');
|
|
20
|
+
var { ProviderPlugin } = require('../../contracts/plugin-interface');
|
|
21
|
+
var { StateStore, FileSystemAdapter } = require('../../runtime/state-store');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Minimal YAML-like parser for task.md
|
|
25
|
+
* Extracts the task table rows (WP-xxx entries) and status info.
|
|
26
|
+
*/
|
|
27
|
+
function parseTaskMarkdown(content) {
|
|
28
|
+
var lines = content.split('\n');
|
|
29
|
+
var tasks = [];
|
|
30
|
+
var stats = { total: 0, completed: 0, inProgress: 0, pending: 0 };
|
|
31
|
+
|
|
32
|
+
// Find the table header row that starts with | WP |
|
|
33
|
+
var tableStarted = false;
|
|
34
|
+
var headerSkipped = false;
|
|
35
|
+
var separatorSkipped = false;
|
|
36
|
+
|
|
37
|
+
for (var i = 0; i < lines.length; i++) {
|
|
38
|
+
var line = lines[i];
|
|
39
|
+
|
|
40
|
+
if (!tableStarted) {
|
|
41
|
+
if (line.indexOf('| WP ') === 0 || line.indexOf('| WP\t') === 0) {
|
|
42
|
+
tableStarted = true;
|
|
43
|
+
headerSkipped = true; // this line IS the header, already skipped by continue
|
|
44
|
+
}
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// The first line after tableStarted is the header - skip it
|
|
49
|
+
if (!headerSkipped) {
|
|
50
|
+
headerSkipped = true;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// The second line is the separator (|---|---|...) - skip it
|
|
55
|
+
if (!separatorSkipped) {
|
|
56
|
+
separatorSkipped = true;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Parse data rows
|
|
61
|
+
var trimmed = line.trim();
|
|
62
|
+
if (!trimmed || trimmed.indexOf('|') !== 0) {
|
|
63
|
+
// End of table
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
var cells = trimmed.split('|').filter(function (c) { return c.trim() !== ''; });
|
|
68
|
+
if (cells.length < 2) continue;
|
|
69
|
+
|
|
70
|
+
var wpId = cells[0].trim();
|
|
71
|
+
if (!wpId.match(/^WP-\d+$/)) continue;
|
|
72
|
+
|
|
73
|
+
var title = cells.length > 1 ? cells[1].trim() : '';
|
|
74
|
+
var statusCell = cells.length > 2 ? cells[2].trim() : '';
|
|
75
|
+
var phase = cells.length > 3 ? cells[3].trim() : '';
|
|
76
|
+
var priority = cells.length > 4 ? cells[4].trim() : '';
|
|
77
|
+
var deps = cells.length > 5 ? cells[5].trim() : '';
|
|
78
|
+
var estimate = cells.length > 6 ? cells[6].trim() : '';
|
|
79
|
+
|
|
80
|
+
var status = 'pending';
|
|
81
|
+
if (statusCell.indexOf('完成') !== -1 || statusCell.indexOf('Completed') !== -1) {
|
|
82
|
+
status = 'completed';
|
|
83
|
+
} else if (statusCell.indexOf('进行') !== -1 || statusCell.indexOf('In Progress') !== -1) {
|
|
84
|
+
status = 'in_progress';
|
|
85
|
+
} else if (statusCell.indexOf('待开始') !== -1 || statusCell.indexOf('Pending') !== -1) {
|
|
86
|
+
status = 'pending';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
stats.total++;
|
|
90
|
+
if (status === 'completed') stats.completed++;
|
|
91
|
+
else if (status === 'in_progress') stats.inProgress++;
|
|
92
|
+
else stats.pending++;
|
|
93
|
+
|
|
94
|
+
tasks.push({
|
|
95
|
+
id: wpId,
|
|
96
|
+
title: title,
|
|
97
|
+
status: status,
|
|
98
|
+
phase: phase,
|
|
99
|
+
priority: priority,
|
|
100
|
+
dependencies: deps ? deps.split(',').map(function (d) { return d.trim(); }) : [],
|
|
101
|
+
estimate: estimate,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return { tasks: tasks, stats: stats };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* StateStoreProvider - provides state access and task parsing
|
|
110
|
+
*/
|
|
111
|
+
class StateStoreProvider extends ProviderPlugin {
|
|
112
|
+
constructor() {
|
|
113
|
+
super();
|
|
114
|
+
this.name = 'provider-state-store';
|
|
115
|
+
this.version = '1.0.0';
|
|
116
|
+
this.description = 'State Store Provider';
|
|
117
|
+
this.provides = 'provider:state-store';
|
|
118
|
+
this.dependencies = {};
|
|
119
|
+
|
|
120
|
+
/** @type {StateStore|null} */
|
|
121
|
+
this._store = null;
|
|
122
|
+
/** @type {string} */
|
|
123
|
+
this._projectRoot = '';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Called when the plugin is activated.
|
|
128
|
+
* Initializes the StateStore with the project root path.
|
|
129
|
+
*
|
|
130
|
+
* @param {PluginContext} context
|
|
131
|
+
*/
|
|
132
|
+
async onActivate(context) {
|
|
133
|
+
this._projectRoot = this._resolveProjectRoot();
|
|
134
|
+
var stateFilePath = path.join(this._projectRoot, '.claude-state');
|
|
135
|
+
this._store = new StateStore({ filePath: stateFilePath });
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Factory method - returns the provider instance (this provider itself).
|
|
140
|
+
*
|
|
141
|
+
* @param {PluginContext} context
|
|
142
|
+
* @returns {Promise<object>} the state store provider API
|
|
143
|
+
*/
|
|
144
|
+
async factory(context) {
|
|
145
|
+
var self = this;
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
/**
|
|
149
|
+
* Get a value by dot-notation key from the state store.
|
|
150
|
+
* @param {string} key - e.g. 'harness.state'
|
|
151
|
+
* @returns {Promise<*|undefined>}
|
|
152
|
+
*/
|
|
153
|
+
get: function (key) {
|
|
154
|
+
return self._store.get(key);
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Set a value by dot-notation key.
|
|
159
|
+
* @param {string} key
|
|
160
|
+
* @param {*} value
|
|
161
|
+
* @returns {Promise<void>}
|
|
162
|
+
*/
|
|
163
|
+
set: function (key, value) {
|
|
164
|
+
return self._store.set(key, value);
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Delete a key from the state store.
|
|
169
|
+
* @param {string} key
|
|
170
|
+
* @returns {Promise<void>}
|
|
171
|
+
*/
|
|
172
|
+
delete: function (key) {
|
|
173
|
+
return self._store.delete(key);
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* List all stored keys.
|
|
178
|
+
* @returns {Promise<string[]>}
|
|
179
|
+
*/
|
|
180
|
+
keys: function () {
|
|
181
|
+
return self._store.keys();
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Subscribe to changes on a specific key.
|
|
186
|
+
* @param {string} key
|
|
187
|
+
* @param {Function} callback - callback(key, oldValue, newValue)
|
|
188
|
+
* @returns {{ unsubscribe: Function }}
|
|
189
|
+
*/
|
|
190
|
+
subscribe: function (key, callback) {
|
|
191
|
+
return self._store.subscribe(key, callback);
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Parse task.md into a structured task list.
|
|
196
|
+
* @returns {Promise<{ tasks: object[], stats: object }>}
|
|
197
|
+
*/
|
|
198
|
+
getTasks: function () {
|
|
199
|
+
return self._parseTasks();
|
|
200
|
+
},
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Get the raw state store instance for advanced usage.
|
|
204
|
+
* @returns {StateStore}
|
|
205
|
+
*/
|
|
206
|
+
getStore: function () {
|
|
207
|
+
return self._store;
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Parse the task.md file.
|
|
214
|
+
* @returns {Promise<{ tasks: object[], stats: object }>}
|
|
215
|
+
*/
|
|
216
|
+
async _parseTasks() {
|
|
217
|
+
var taskFile = path.join(this._projectRoot, 'task.md');
|
|
218
|
+
try {
|
|
219
|
+
var content = fs.readFileSync(taskFile, 'utf-8');
|
|
220
|
+
return parseTaskMarkdown(content);
|
|
221
|
+
} catch (err) {
|
|
222
|
+
return { tasks: [], stats: { total: 0, completed: 0, inProgress: 0, pending: 0 } };
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Resolve the project root directory.
|
|
228
|
+
* Walks up from cwd to find a directory containing task.md or .claude/.
|
|
229
|
+
* @returns {string}
|
|
230
|
+
*/
|
|
231
|
+
_resolveProjectRoot() {
|
|
232
|
+
var dir = process.cwd();
|
|
233
|
+
for (var i = 0; i < 10; i++) {
|
|
234
|
+
if (fs.existsSync(path.join(dir, 'task.md'))) return dir;
|
|
235
|
+
if (fs.existsSync(path.join(dir, '.claude'))) return dir;
|
|
236
|
+
var parent = path.dirname(dir);
|
|
237
|
+
if (parent === dir) break;
|
|
238
|
+
dir = parent;
|
|
239
|
+
}
|
|
240
|
+
return process.cwd();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
module.exports = StateStoreProvider;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "skill-agent-dispatcher",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "skill",
|
|
5
|
+
"description": "子代理批量调度 Skill - 基于 Agent Teams 机制的子代理批量任务调度,支持角色赋能、记忆注入、依赖分析和并行执行",
|
|
6
|
+
"triggers": ["批量执行", "并行执行", "调度子代理", "agent-dispatcher", "batch execute", "parallel execute", "dispatch agents"],
|
|
7
|
+
"dependencies": ["provider:role-registry", "provider:memory-store"],
|
|
8
|
+
"provides": ["skill:agent-dispatcher"],
|
|
9
|
+
"metadata": {
|
|
10
|
+
"gatedByCode": true
|
|
11
|
+
},
|
|
12
|
+
"config": {}
|
|
13
|
+
}
|