@lumenflow/cli 3.19.0 → 3.21.0
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/dist/gates-runners.js +5 -4
- package/dist/gates-runners.js.map +1 -1
- package/dist/gates-utils.js +71 -0
- package/dist/gates-utils.js.map +1 -1
- package/dist/init-templates.js +30 -22
- package/dist/init-templates.js.map +1 -1
- package/dist/wu-prune.js +2 -2
- package/dist/wu-prune.js.map +1 -1
- package/dist/wu-verify.js +22 -17
- package/dist/wu-verify.js.map +1 -1
- package/package.json +8 -8
- package/packs/agent-runtime/.turbo/turbo-build.log +1 -1
- package/packs/agent-runtime/package.json +1 -1
- package/packs/sidekick/.turbo/turbo-build.log +1 -1
- package/packs/sidekick/README.md +118 -113
- package/packs/sidekick/manifest-schema.ts +15 -228
- package/packs/sidekick/manifest.ts +107 -7
- package/packs/sidekick/manifest.yaml +199 -1
- package/packs/sidekick/package.json +4 -1
- package/packs/sidekick/policy-factory.ts +38 -0
- package/packs/sidekick/tool-impl/channel-tools.ts +99 -0
- package/packs/sidekick/tool-impl/memory-tools.ts +86 -1
- package/packs/sidekick/tool-impl/routine-tools.ts +156 -2
- package/packs/sidekick/tool-impl/storage.ts +6 -5
- package/packs/sidekick/tool-impl/task-tools.ts +186 -4
- package/packs/software-delivery/.turbo/turbo-build.log +1 -1
- package/packs/software-delivery/package.json +1 -1
- package/templates/core/.lumenflow/constraints.md.template +68 -3
- package/templates/core/LUMENFLOW.md.template +26 -26
- package/templates/core/_frameworks/lumenflow/wu-sizing-guide.md.template +3 -5
- package/templates/core/ai/onboarding/agent-safety-card.md.template +14 -4
- package/templates/core/ai/onboarding/first-wu-mistakes.md.template +96 -0
- package/templates/core/ai/onboarding/quick-ref-commands.md.template +50 -39
- package/templates/core/ai/onboarding/rapid-prototyping.md +2 -1
- package/templates/core/ai/onboarding/starting-prompt.md.template +5 -4
- package/templates/core/ai/onboarding/troubleshooting-wu-done.md.template +69 -1
package/dist/wu-verify.js
CHANGED
|
@@ -19,23 +19,28 @@
|
|
|
19
19
|
import { createWUParser, WU_OPTIONS } from '@lumenflow/core/arg-parser';
|
|
20
20
|
import { EXIT_CODES } from '@lumenflow/core/wu-constants';
|
|
21
21
|
import { verifyWUComplete, debugSummary } from '@lumenflow/agent/verification';
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
22
|
+
import { runCLI } from './cli-entry-point.js';
|
|
23
|
+
// WU-2482: Wrap in async main() + runCLI so --help exits 0 via ProcessExitError handling.
|
|
24
|
+
async function main() {
|
|
25
|
+
const opts = createWUParser({
|
|
26
|
+
name: 'wu-verify',
|
|
27
|
+
description: 'Verify WU completion (stamp, commit, clean tree)',
|
|
28
|
+
options: [WU_OPTIONS.id],
|
|
29
|
+
required: ['id'],
|
|
30
|
+
});
|
|
31
|
+
const id = opts.id;
|
|
32
|
+
try {
|
|
33
|
+
const result = verifyWUComplete(id);
|
|
34
|
+
const message = debugSummary(result);
|
|
35
|
+
console.log(message);
|
|
36
|
+
process.exit(result.complete ? EXIT_CODES.SUCCESS : EXIT_CODES.ERROR);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
console.error(`Verification error: ${error instanceof Error ? error.message : String(error)}`);
|
|
40
|
+
process.exit(EXIT_CODES.ERROR);
|
|
41
|
+
}
|
|
35
42
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
console.error(`Verification error: ${error instanceof Error ? error.message : String(error)}`);
|
|
39
|
-
process.exit(EXIT_CODES.ERROR);
|
|
43
|
+
if (import.meta.main) {
|
|
44
|
+
void runCLI(main);
|
|
40
45
|
}
|
|
41
46
|
//# sourceMappingURL=wu-verify.js.map
|
package/dist/wu-verify.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wu-verify.js","sourceRoot":"","sources":["../src/wu-verify.ts"],"names":[],"mappings":";AACA,iCAAiC;AACjC,yCAAyC;AACzC;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"wu-verify.js","sourceRoot":"","sources":["../src/wu-verify.ts"],"names":[],"mappings":";AACA,iCAAiC;AACjC,yCAAyC;AACzC;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC/E,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,0FAA0F;AAC1F,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,cAAc,CAAC;QAC1B,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,kDAAkD;QAC/D,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;QACxB,QAAQ,EAAE,CAAC,IAAI,CAAC;KACjB,CAAC,CAAC;IAEH,MAAM,EAAE,GAAW,IAAI,CAAC,EAAE,CAAC;IAE3B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACpC,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACxE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,uBAAuB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/F,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;AACH,CAAC;AAED,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACrB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lumenflow/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.21.0",
|
|
4
4
|
"description": "Command-line interface for LumenFlow workflow framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lumenflow",
|
|
@@ -186,13 +186,13 @@
|
|
|
186
186
|
"xstate": "^5.28.0",
|
|
187
187
|
"yaml": "^2.8.2",
|
|
188
188
|
"zod": "^4.3.6",
|
|
189
|
-
"@lumenflow/
|
|
190
|
-
"@lumenflow/
|
|
191
|
-
"@lumenflow/
|
|
192
|
-
"@lumenflow/
|
|
193
|
-
"@lumenflow/
|
|
194
|
-
"@lumenflow/
|
|
195
|
-
"@lumenflow/
|
|
189
|
+
"@lumenflow/control-plane-sdk": "3.21.0",
|
|
190
|
+
"@lumenflow/core": "3.21.0",
|
|
191
|
+
"@lumenflow/initiatives": "3.21.0",
|
|
192
|
+
"@lumenflow/kernel": "3.21.0",
|
|
193
|
+
"@lumenflow/memory": "3.21.0",
|
|
194
|
+
"@lumenflow/metrics": "3.21.0",
|
|
195
|
+
"@lumenflow/agent": "3.21.0"
|
|
196
196
|
},
|
|
197
197
|
"devDependencies": {
|
|
198
198
|
"@vitest/coverage-v8": "^4.0.18",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
> @lumenflow/packs-agent-runtime@3.
|
|
2
|
+
> @lumenflow/packs-agent-runtime@3.21.0 build /home/runner/work/lumenflow-dev/lumenflow-dev/packages/@lumenflow/packs/agent-runtime
|
|
3
3
|
> tsc
|
|
4
4
|
|
package/packs/sidekick/README.md
CHANGED
|
@@ -1,194 +1,199 @@
|
|
|
1
1
|
# Sidekick Pack
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Workspace-local productivity pack for the LumenFlow kernel. Sidekick manages tasks, memory,
|
|
4
|
+
channels, routines, and status under `.sidekick/`, while keeping every tool call inside the normal
|
|
5
|
+
kernel scope, policy, and evidence pipeline.
|
|
6
6
|
|
|
7
7
|
## Status
|
|
8
8
|
|
|
9
|
-
**Version**: 0.1.0 (pre-release)
|
|
10
|
-
**License**: AGPL-3.0-only
|
|
9
|
+
**Version**: `0.1.0` (pre-release)
|
|
10
|
+
**License**: `AGPL-3.0-only`
|
|
11
11
|
|
|
12
12
|
## Tool Groups
|
|
13
13
|
|
|
14
|
-
| Group | Tools
|
|
15
|
-
| ------- |
|
|
16
|
-
| Task | `task:create`, `task:list`, `task:complete`, `task:schedule` | Create,
|
|
17
|
-
| Memory | `memory:store`, `memory:recall`, `memory:forget`
|
|
18
|
-
| Channel | `channel:configure`, `channel:send`, `channel:receive`
|
|
19
|
-
| Routine | `routine:create`, `routine:list`, `routine:run`
|
|
20
|
-
| System | `sidekick:init`, `sidekick:status`, `sidekick:export`
|
|
21
|
-
|
|
22
|
-
**Total**: 16 tools
|
|
23
|
-
|
|
24
|
-
## Key Design Decisions
|
|
25
|
-
|
|
26
|
-
- **`.sidekick/` is workspace-local storage.** All data lives under the project
|
|
27
|
-
root in a `.sidekick/` directory managed by the `StoragePort` abstraction.
|
|
28
|
-
- **`routine:run` returns a plan only.** It resolves the routine definition and
|
|
29
|
-
returns the ordered list of steps with their inputs. It does not execute them.
|
|
30
|
-
- **`sidekick:export` is read-only.** It returns all stored data as a JSON
|
|
31
|
-
structure. It does not write files to disk.
|
|
32
|
-
- **Every write tool supports `dry_run`.** When `dry_run: true`, the tool
|
|
33
|
-
validates input and returns what it would do, without persisting changes.
|
|
34
|
-
- **Pack manifest is the contract.** There is no separate contract package. The
|
|
35
|
-
`manifest.yaml` file defines tool names, schemas, scopes, and policies.
|
|
14
|
+
| Group | Tools | Description |
|
|
15
|
+
| ------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------- |
|
|
16
|
+
| Task | `task:create`, `task:list`, `task:update`, `task:cancel`, `task:complete`, `task:schedule` | Create, manage, cancel, complete, and schedule local tasks |
|
|
17
|
+
| Memory | `memory:store`, `memory:recall`, `memory:update`, `memory:forget` | Persist and edit reusable workspace knowledge |
|
|
18
|
+
| Channel | `channel:configure`, `channel:list`, `channel:delete`, `channel:send`, `channel:receive` | Discover and manage named local message channels |
|
|
19
|
+
| Routine | `routine:create`, `routine:list`, `routine:update`, `routine:delete`, `routine:run` | Define, stop, inspect, and remove plan-only routines |
|
|
20
|
+
| System | `sidekick:init`, `sidekick:status`, `sidekick:export` | Bootstrap, health check, and export Sidekick-managed state |
|
|
36
21
|
|
|
37
|
-
|
|
22
|
+
**Total**: 23 tools
|
|
38
23
|
|
|
39
|
-
|
|
24
|
+
## Behavior Notes
|
|
40
25
|
|
|
41
|
-
|
|
26
|
+
- `.sidekick/` is the pack-owned storage root.
|
|
27
|
+
- `routine:run` is plan-only. It returns the resolved steps and never executes them.
|
|
28
|
+
- `routine:update` with `enabled: false` is the stop primitive for routines.
|
|
29
|
+
- `task:cancel` is the destructive task terminal state; it is separate from `task:complete`.
|
|
30
|
+
- `sidekick:export` is read-only. It returns data and does not write export artifacts.
|
|
31
|
+
- All write-capable and destructive tools support `dry_run`.
|
|
32
|
+
- Destructive Sidekick tools are approval-gated through the pack policy factory.
|
|
42
33
|
|
|
43
|
-
-
|
|
44
|
-
- HTTP surface running (for HTTP dispatch tests)
|
|
34
|
+
### Approval-Gated Destructive Tools
|
|
45
35
|
|
|
46
|
-
|
|
36
|
+
These tools require policy evaluation to return `approval_required` before execution:
|
|
47
37
|
|
|
48
|
-
|
|
49
|
-
|
|
38
|
+
- `task:cancel`
|
|
39
|
+
- `memory:forget`
|
|
40
|
+
- `channel:delete`
|
|
41
|
+
- `routine:delete`
|
|
42
|
+
|
|
43
|
+
The permission label helps classify them as destructive, but the actual pause comes from the pack
|
|
44
|
+
policy path and kernel approval flow.
|
|
45
|
+
|
|
46
|
+
## Manual Smoke Flow
|
|
47
|
+
|
|
48
|
+
Use this sequence after installation or whenever you want to smoke test the current contract.
|
|
49
|
+
|
|
50
|
+
### 1. Initialize storage
|
|
51
|
+
|
|
52
|
+
```text
|
|
50
53
|
tool: sidekick:init
|
|
51
54
|
input: {}
|
|
52
55
|
```
|
|
53
56
|
|
|
54
|
-
Expected: `
|
|
57
|
+
Expected: `initialized: true` and a `.sidekick/` root path.
|
|
55
58
|
|
|
56
|
-
###
|
|
59
|
+
### 2. Create and update a task
|
|
57
60
|
|
|
58
|
-
```
|
|
61
|
+
```text
|
|
59
62
|
tool: task:create
|
|
60
63
|
input: { "title": "Review docs", "priority": "P1", "tags": ["docs"] }
|
|
61
64
|
```
|
|
62
65
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
```text
|
|
67
|
+
tool: task:update
|
|
68
|
+
input: {
|
|
69
|
+
"id": "<task-id>",
|
|
70
|
+
"description": "Check final Sidekick contract",
|
|
71
|
+
"due_at": "2026-03-31T00:00:00Z"
|
|
72
|
+
}
|
|
70
73
|
```
|
|
71
74
|
|
|
72
|
-
Expected:
|
|
75
|
+
Expected: `task:list` returns the updated task metadata.
|
|
73
76
|
|
|
74
|
-
###
|
|
77
|
+
### 3. Store and update memory
|
|
75
78
|
|
|
76
|
-
```
|
|
79
|
+
```text
|
|
77
80
|
tool: memory:store
|
|
78
|
-
input: { "type": "note", "content": "Sidekick
|
|
81
|
+
input: { "type": "note", "content": "Sidekick docs updated", "tags": ["docs"] }
|
|
79
82
|
```
|
|
80
83
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
tool: memory:recall
|
|
87
|
-
input: { "query": "validated", "type": "note" }
|
|
84
|
+
```text
|
|
85
|
+
tool: memory:update
|
|
86
|
+
input: { "id": "<memory-id>", "type": "snippet", "content": "task:cancel is approval-gated" }
|
|
88
87
|
```
|
|
89
88
|
|
|
90
|
-
Expected:
|
|
89
|
+
Expected: `memory:recall` returns the edited record.
|
|
91
90
|
|
|
92
|
-
###
|
|
91
|
+
### 4. Create and stop a routine
|
|
93
92
|
|
|
94
|
-
```
|
|
93
|
+
```text
|
|
95
94
|
tool: routine:create
|
|
96
95
|
input: {
|
|
97
96
|
"name": "daily-review",
|
|
98
97
|
"steps": [
|
|
99
98
|
{ "tool": "task:list", "input": { "status": "pending" } },
|
|
100
99
|
{ "tool": "sidekick:status", "input": {} }
|
|
101
|
-
]
|
|
100
|
+
],
|
|
101
|
+
"enabled": true
|
|
102
102
|
}
|
|
103
103
|
```
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
```text
|
|
106
|
+
tool: routine:update
|
|
107
|
+
input: { "id": "<routine-id>", "enabled": false }
|
|
108
|
+
```
|
|
106
109
|
|
|
107
|
-
|
|
110
|
+
Expected: `routine:list` still shows the routine, while `routine:list { "enabled_only": true }`
|
|
111
|
+
excludes it.
|
|
108
112
|
|
|
109
|
-
|
|
113
|
+
### 5. Inspect a routine plan
|
|
114
|
+
|
|
115
|
+
```text
|
|
110
116
|
tool: routine:run
|
|
111
|
-
input: { "id": "<routine-id
|
|
117
|
+
input: { "id": "<routine-id>" }
|
|
112
118
|
```
|
|
113
119
|
|
|
114
|
-
Expected: A plan object listing the
|
|
115
|
-
side-effects -- the steps are NOT executed.
|
|
120
|
+
Expected: A plan object listing the ordered steps. No side effects occur.
|
|
116
121
|
|
|
117
|
-
###
|
|
122
|
+
### 6. Check channel discovery
|
|
118
123
|
|
|
119
|
-
```
|
|
120
|
-
tool:
|
|
124
|
+
```text
|
|
125
|
+
tool: channel:send
|
|
126
|
+
input: { "channel": "alerts", "content": "Docs smoke flow" }
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
```text
|
|
130
|
+
tool: channel:list
|
|
121
131
|
input: {}
|
|
122
132
|
```
|
|
123
133
|
|
|
124
|
-
Expected:
|
|
125
|
-
`
|
|
134
|
+
Expected: A local channel entry with stable metadata such as `message_count` and
|
|
135
|
+
`last_message_at`.
|
|
126
136
|
|
|
127
|
-
###
|
|
137
|
+
### 7. Verify a destructive dry run
|
|
128
138
|
|
|
129
|
-
```
|
|
130
|
-
tool:
|
|
131
|
-
input: { "
|
|
139
|
+
```text
|
|
140
|
+
tool: task:cancel
|
|
141
|
+
input: { "id": "<task-id>", "dry_run": true }
|
|
132
142
|
```
|
|
133
143
|
|
|
134
|
-
Expected:
|
|
144
|
+
Expected: The response previews the canceled task and includes `dry_run: true`, while
|
|
145
|
+
`task:list { "status": "pending" }` still shows the task as pending.
|
|
135
146
|
|
|
136
|
-
###
|
|
147
|
+
### 8. Verify approval-gated destructive behavior
|
|
137
148
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
input: { "id": "<task-id-from-step-2>", "note": "Smoke test passed" }
|
|
141
|
-
```
|
|
149
|
+
Run `task:cancel`, `memory:forget`, `channel:delete`, or `routine:delete` through the kernel
|
|
150
|
+
runtime or host surface that evaluates policies.
|
|
142
151
|
|
|
143
|
-
Expected:
|
|
152
|
+
Expected: The first attempt returns `APPROVAL_REQUIRED`. After approval resolution, the tool runs
|
|
153
|
+
and the audit trail reflects the final delete or cancel transition.
|
|
144
154
|
|
|
145
|
-
###
|
|
155
|
+
### 9. Export
|
|
146
156
|
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
-d '{ "context": { "task_id": "smoke-test", "workspace_id": "test" } }'
|
|
157
|
+
```text
|
|
158
|
+
tool: sidekick:export
|
|
159
|
+
input: { "include_audit": true }
|
|
151
160
|
```
|
|
152
161
|
|
|
153
|
-
Expected:
|
|
154
|
-
|
|
155
|
-
### Dry Run Verification
|
|
156
|
-
|
|
157
|
-
Repeat Step 2 with `"dry_run": true` added to the input. Verify that the
|
|
158
|
-
response includes `"dry_run": true` and that `task:list` does not return the
|
|
159
|
-
dry-run task.
|
|
162
|
+
Expected: A full JSON snapshot of stores plus audit events.
|
|
160
163
|
|
|
161
164
|
## Validation
|
|
162
165
|
|
|
163
166
|
```bash
|
|
164
|
-
#
|
|
167
|
+
# Pack contract and integrity
|
|
165
168
|
pnpm pack:validate --id sidekick
|
|
166
169
|
|
|
167
|
-
#
|
|
168
|
-
|
|
170
|
+
# Sidekick tool and manifest tests
|
|
171
|
+
pnpm vitest run packages/@lumenflow/packs/sidekick/__tests__/
|
|
169
172
|
|
|
170
|
-
#
|
|
171
|
-
|
|
173
|
+
# Kernel approval coverage for Sidekick destructive tools
|
|
174
|
+
pnpm vitest run packages/@lumenflow/kernel/src/__tests__/runtime.test.ts
|
|
172
175
|
```
|
|
173
176
|
|
|
174
|
-
## Storage
|
|
177
|
+
## Storage Layout
|
|
175
178
|
|
|
176
|
-
|
|
177
|
-
(`FsStoragePort`). Each store (tasks, memories, channels, messages, routines)
|
|
178
|
-
is a JSON array file under `.sidekick/`. An append-only `audit.jsonl` file
|
|
179
|
-
records every tool invocation.
|
|
179
|
+
Sidekick uses a `StoragePort` abstraction with a filesystem adapter. The persisted layout is:
|
|
180
180
|
|
|
181
|
-
```
|
|
181
|
+
```text
|
|
182
182
|
.sidekick/
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
channels
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
183
|
+
audit/
|
|
184
|
+
events.jsonl
|
|
185
|
+
channels/
|
|
186
|
+
channels.json
|
|
187
|
+
messages.json
|
|
188
|
+
memory/
|
|
189
|
+
memories.json
|
|
190
|
+
routines/
|
|
191
|
+
routines.json
|
|
192
|
+
tasks/
|
|
193
|
+
tasks.json
|
|
189
194
|
```
|
|
190
195
|
|
|
191
196
|
## Contributing
|
|
192
197
|
|
|
193
|
-
This pack follows the LumenFlow
|
|
194
|
-
|
|
198
|
+
This pack follows the LumenFlow workflow. See the repository `LUMENFLOW.md` and workspace rules for
|
|
199
|
+
delivery expectations.
|