claude-flow-novice 2.14.11 → 2.14.13

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.
@@ -0,0 +1,113 @@
1
+ #!/bin/bash
2
+ # Retrieve CFN Loop task context from Redis
3
+ # Used by CLI-spawned agents to get structured context from orchestrator
4
+ #
5
+ # Usage:
6
+ # get-context.sh --task-id <id> [--namespace <ns>]
7
+ # get-context.sh --task-id <id> --key <key> [--namespace <ns>]
8
+ # get-context.sh <task_id> (legacy mode)
9
+
10
+ set -euo pipefail
11
+
12
+ # Initialize variables
13
+ TASK_ID=""
14
+ KEY=""
15
+ NAMESPACE="swarm"
16
+ FORMAT="json" # json or raw
17
+
18
+ # Parse arguments
19
+ while [[ $# -gt 0 ]]; do
20
+ case $1 in
21
+ --task-id)
22
+ TASK_ID="$2"
23
+ shift 2
24
+ ;;
25
+ --key)
26
+ KEY="$2"
27
+ shift 2
28
+ ;;
29
+ --namespace)
30
+ NAMESPACE="$2"
31
+ shift 2
32
+ ;;
33
+ --format)
34
+ FORMAT="$2"
35
+ shift 2
36
+ ;;
37
+ *)
38
+ # Legacy mode: positional argument
39
+ if [ -z "$TASK_ID" ]; then
40
+ TASK_ID="$1"
41
+ fi
42
+ shift
43
+ ;;
44
+ esac
45
+ done
46
+
47
+ # Validate required arguments
48
+ if [ -z "$TASK_ID" ]; then
49
+ echo "Error: --task-id or TASK_ID required" >&2
50
+ echo "Usage: $0 --task-id <id> [--key <key>] [--namespace <ns>] [--format <json|raw>]" >&2
51
+ echo " or: $0 <task_id> (legacy)" >&2
52
+ exit 1
53
+ fi
54
+
55
+ REDIS_KEY="${NAMESPACE}:${TASK_ID}:context"
56
+
57
+ # Check if context exists
58
+ if ! redis-cli EXISTS "$REDIS_KEY" >/dev/null 2>&1; then
59
+ echo "⚠️ No context found for task: $TASK_ID" >&2
60
+ exit 1
61
+ fi
62
+
63
+ # Handle specific key retrieval
64
+ if [ -n "$KEY" ]; then
65
+ VALUE=$(redis-cli HGET "$REDIS_KEY" "$KEY" 2>/dev/null || echo "")
66
+ if [ -z "$VALUE" ]; then
67
+ echo "⚠️ Key '$KEY' not found in context for task: $TASK_ID" >&2
68
+ exit 1
69
+ fi
70
+
71
+ if [ "$FORMAT" = "raw" ]; then
72
+ echo "$VALUE"
73
+ else
74
+ echo "{\"$KEY\":$VALUE}"
75
+ fi
76
+ exit 0
77
+ fi
78
+
79
+ # Handle full context retrieval
80
+ ALL_FIELDS=$(redis-cli HGETALL "$REDIS_KEY" 2>/dev/null || echo "")
81
+
82
+ if [ -z "$ALL_FIELDS" ]; then
83
+ echo "⚠️ Empty context for task: $TASK_ID" >&2
84
+ exit 1
85
+ fi
86
+
87
+ # Format as JSON
88
+ if [ "$FORMAT" = "json" ]; then
89
+ echo "{"
90
+ first=true
91
+ while IFS= read -r field; do
92
+ if [ -z "$field" ]; then continue; fi
93
+ if [ "$first" = true ]; then
94
+ first=false
95
+ else
96
+ echo ","
97
+ fi
98
+ # Skip empty lines and properly format JSON values
99
+ if [[ $field =~ ^[0-9]+$ ]]; then
100
+ # Numeric value
101
+ echo -n " \"$field\": $(redis-cli HGET "$REDIS_KEY" "$field")"
102
+ else
103
+ # String value
104
+ value=$(redis-cli HGET "$REDIS_KEY" "$field" | sed 's/"/\\"/g')
105
+ echo -n " \"$field\": \"$value\""
106
+ fi
107
+ done <<< "$ALL_FIELDS"
108
+ echo ""
109
+ echo "}"
110
+ else
111
+ # Raw format
112
+ redis-cli HGETALL "$REDIS_KEY"
113
+ fi
@@ -1,34 +1,89 @@
1
1
  #!/bin/bash
2
2
  # Store CFN Loop task context in Redis
3
- # Used by orchestrator to pass context to CLI-spawned agents
3
+ # Used by orchestrator to pass structured context to CLI-spawned agents
4
4
  #
5
- # Usage: store-context.sh <task_id> <context_json>
5
+ # Usage:
6
+ # store-context.sh --task-id <id> --key <key> --value <value> [--namespace <ns>]
7
+ # store-context.sh <task_id> <context_json> (legacy mode)
6
8
 
7
9
  set -euo pipefail
8
10
 
9
- TASK_ID="${1:-}"
10
- CONTEXT="${2:-}"
11
+ # Initialize variables
12
+ TASK_ID=""
13
+ KEY=""
14
+ VALUE=""
15
+ NAMESPACE="swarm"
16
+ CONTEXT=""
11
17
 
18
+ # Parse arguments
19
+ while [[ $# -gt 0 ]]; do
20
+ case $1 in
21
+ --task-id)
22
+ TASK_ID="$2"
23
+ shift 2
24
+ ;;
25
+ --key)
26
+ KEY="$2"
27
+ shift 2
28
+ ;;
29
+ --value)
30
+ VALUE="$2"
31
+ shift 2
32
+ ;;
33
+ --namespace)
34
+ NAMESPACE="$2"
35
+ shift 2
36
+ ;;
37
+ *)
38
+ # Legacy mode: positional arguments
39
+ if [ -z "$TASK_ID" ]; then
40
+ TASK_ID="$1"
41
+ elif [ -z "$CONTEXT" ]; then
42
+ CONTEXT="$1"
43
+ fi
44
+ shift
45
+ ;;
46
+ esac
47
+ done
48
+
49
+ # Validate required arguments
12
50
  if [ -z "$TASK_ID" ]; then
13
- echo "Error: TASK_ID required" >&2
14
- echo "Usage: $0 <task_id> <context_json>" >&2
51
+ echo "Error: --task-id or TASK_ID required" >&2
52
+ echo "Usage: $0 --task-id <id> --key <key> --value <value> [--namespace <ns>]" >&2
53
+ echo " or: $0 <task_id> <context_json> (legacy)" >&2
15
54
  exit 1
16
55
  fi
17
56
 
18
- if [ -z "$CONTEXT" ]; then
19
- echo "Error: CONTEXT required" >&2
20
- echo "Usage: $0 <task_id> <context_json>" >&2
21
- exit 1
57
+ # Handle structured mode (new)
58
+ if [ -n "$KEY" ] && [ -n "$VALUE" ]; then
59
+ # Store structured context with specific key
60
+ REDIS_KEY="${NAMESPACE}:${TASK_ID}:context"
61
+
62
+ redis-cli HSET "$REDIS_KEY" \
63
+ "$KEY" "$VALUE" \
64
+ "updated_at" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
65
+ > /dev/null
66
+
67
+ # Set TTL (24 hours)
68
+ redis-cli EXPIRE "$REDIS_KEY" 86400 > /dev/null
69
+
70
+ echo "✅ Context stored: $KEY for task: $TASK_ID"
71
+ exit 0
22
72
  fi
23
73
 
24
- # Store context in Redis
25
- redis-cli HSET "cfn_loop:task:${TASK_ID}:context" \
26
- "task_description" "$CONTEXT" \
27
- "stored_at" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
28
- > /dev/null
74
+ # Handle legacy mode
75
+ if [ -n "$CONTEXT" ]; then
76
+ redis-cli HSET "swarm:${TASK_ID}:context" \
77
+ "task_description" "$CONTEXT" \
78
+ "stored_at" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
79
+ > /dev/null
80
+
81
+ # Set TTL (24 hours)
82
+ redis-cli EXPIRE "swarm:${TASK_ID}:context" 86400 > /dev/null
29
83
 
30
- # Set TTL (24 hours)
31
- redis-cli EXPIRE "cfn_loop:task:${TASK_ID}:context" 86400 > /dev/null
84
+ echo "✅ Context stored for task: $TASK_ID"
85
+ exit 0
86
+ fi
32
87
 
33
- echo " Context stored for task: $TASK_ID"
34
- exit 0
88
+ echo "Error: Either --key/--value or <context_json> required" >&2
89
+ exit 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-flow-novice",
3
- "version": "2.14.11",
3
+ "version": "2.14.13",
4
4
  "description": "AI agent orchestration framework with namespace-isolated skills, agents, and CFN Loop validation. Safe installation with ~0.01% collision risk.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -227,12 +227,65 @@ async function installLizard() {
227
227
  console.log(chalk.gray(' or run: ./tools/install-lizard.sh'));
228
228
  }
229
229
 
230
+ // Parse command line arguments
231
+ function parseArgs() {
232
+ const args = process.argv.slice(2);
233
+ const options = {
234
+ force: false
235
+ };
236
+
237
+ for (const arg of args) {
238
+ if (arg === '--force' || arg === '-f') {
239
+ options.force = true;
240
+ }
241
+ }
242
+
243
+ return options;
244
+ }
245
+
230
246
  async function initializeCfnProject() {
231
- // Skip initialization if already initialized (prevents overwrite on every npx call)
247
+ // Parse command line arguments
248
+ const options = parseArgs();
249
+
250
+ // Check initialization status and handle incomplete setups
232
251
  const markerPath = '.claude/.cfn-initialized';
252
+ const requiredPaths = [
253
+ '.claude/agents/cfn-dev-team',
254
+ '.claude/skills',
255
+ '.claude/hooks',
256
+ '.claude/commands'
257
+ ];
258
+
233
259
  if (fs.existsSync(markerPath)) {
234
- // Silently skip - already initialized
235
- return;
260
+ // Check if initialization appears complete
261
+ const missingPaths = requiredPaths.filter(path => !fs.existsSync(path));
262
+
263
+ if (missingPaths.length === 0 && !options.force) {
264
+ console.log(chalk.green('✅ CFN already properly initialized'));
265
+ console.log(chalk.gray(' Use --force to reinitialize'));
266
+ return;
267
+ } else if (options.force) {
268
+ console.log(chalk.yellow('🚀 Force reinitializing CFN...'));
269
+ console.log(chalk.gray('Removing previous installation...'));
270
+ fs.rmSync(markerPath, { force: true });
271
+ // Remove existing directories for clean reinitialization
272
+ requiredPaths.forEach(path => {
273
+ if (fs.existsSync(path)) {
274
+ fs.rmSync(path, { recursive: true, force: true });
275
+ }
276
+ });
277
+ console.log(chalk.gray('Previous installation removed'));
278
+ } else {
279
+ console.log(chalk.yellow('⚠️ CFN initialization incomplete - reinitializing...'));
280
+ console.log(chalk.gray(`Missing components: ${missingPaths.join(', ')}`));
281
+ console.log(chalk.gray('Removing incomplete initialization marker...'));
282
+ fs.rmSync(markerPath, { force: true });
283
+ // Continue with full initialization
284
+ }
285
+ } else {
286
+ if (options.force) {
287
+ console.log(chalk.yellow('🚀 Force initializing CFN...'));
288
+ }
236
289
  }
237
290
 
238
291
  console.log(chalk.blue('\n🚀 Claude Flow Novice CFN Initialization\n'));