@event4u/agent-config 8.4.0 → 8.4.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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +6 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +1 -1
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +1 -1
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +1 -1
- package/dist/mcp/registry-manifest.json +1 -1
- package/package.json +4 -1
- package/src/agent-src/README.md +64 -0
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +497 -0
- package/src/agent-src/scripts/scan-seeder-violations.php +145 -0
- package/src/agent-src/scripts/update_roadmap_progress.ts +1087 -0
- package/src/agent-src/templates/AGENTS.md +34 -0
- package/src/agent-src/templates/scripts/README.md +195 -0
- package/src/agent-src/templates/scripts/check_memory.ts +662 -0
- package/src/agent-src/templates/scripts/check_memory_proposal.ts +370 -0
- package/src/agent-src/templates/scripts/historical-bug-patterns.example.yml +84 -0
- package/src/agent-src/templates/scripts/implement_ticket/__main__.ts +27 -0
- package/src/agent-src/templates/scripts/memory_hash.ts +355 -0
- package/src/agent-src/templates/scripts/memory_lookup.ts +1089 -0
- package/src/agent-src/templates/scripts/memory_report.ts +868 -0
- package/src/agent-src/templates/scripts/memory_signal.ts +444 -0
- package/src/agent-src/templates/scripts/memory_status.ts +215 -0
- package/src/agent-src/templates/scripts/ownership-map.example.yml +87 -0
- package/src/agent-src/templates/scripts/pr-risk-config.example.yml +76 -0
- package/src/agent-src/templates/scripts/pr_review_routing.ts +544 -0
- package/src/agent-src/templates/scripts/pr_risk_review.ts +0 -0
- package/src/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
- package/src/agent-src/templates/scripts/telemetry/boundary.ts +164 -0
- package/src/agent-src/templates/scripts/telemetry/engagement.ts +479 -0
- package/src/agent-src/templates/scripts/telemetry/report_renderer.ts +394 -0
- package/src/agent-src/templates/scripts/telemetry/settings.ts +210 -0
- package/src/agent-src/templates/scripts/telemetry_record.ts +276 -0
- package/src/agent-src/templates/scripts/telemetry_report.ts +211 -0
- package/src/agent-src/templates/scripts/telemetry_status.ts +333 -0
- package/src/agent-src/templates/scripts/tier_usage_report.ts +619 -0
- package/src/agent-src/templates/scripts/work_engine/__main__.ts +14 -0
- package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +1261 -0
- package/src/agent-src/templates/scripts/work_engine/_lib/user_global_paths.ts +329 -0
- package/src/agent-src/templates/scripts/work_engine/cli.ts +206 -0
- package/src/agent-src/templates/scripts/work_engine/cli_args.ts +249 -0
- package/src/agent-src/templates/scripts/work_engine/delivery_state.ts +225 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/analyze.ts +125 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +189 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/index.ts +94 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/memory.ts +193 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/plan.ts +267 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/refine.ts +518 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/report.ts +379 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +268 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +258 -0
- package/src/agent-src/templates/scripts/work_engine/directives/index.ts +32 -0
- package/src/agent-src/templates/scripts/work_engine/directives/mixed/contract.ts +243 -0
- package/src/agent-src/templates/scripts/work_engine/directives/mixed/index.ts +108 -0
- package/src/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +259 -0
- package/src/agent-src/templates/scripts/work_engine/directives/mixed/ui.ts +216 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/_passthrough.ts +40 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/app_spec.ts +241 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +216 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +506 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/design.ts +325 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/index.ts +102 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +462 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +474 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +352 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui_trivial/_skipped.ts +33 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui_trivial/apply.ts +213 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui_trivial/index.ts +111 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui_trivial/refine.ts +126 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui_trivial/report.ts +112 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui_trivial/test.ts +164 -0
- package/src/agent-src/templates/scripts/work_engine/dispatcher.ts +515 -0
- package/src/agent-src/templates/scripts/work_engine/emitters.ts +119 -0
- package/src/agent-src/templates/scripts/work_engine/errors.ts +24 -0
- package/src/agent-src/templates/scripts/work_engine/hook_bootstrap.ts +104 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/_chat_history_base.ts +189 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_append.ts +41 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_halt_append.ts +89 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_gate.ts +193 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +304 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/directive_set_guard.ts +110 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/halt_surface_audit.ts +118 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/index.ts +17 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +161 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/state_shape_validation.ts +45 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/trace.ts +134 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/context.ts +94 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/events.ts +58 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/exceptions.ts +85 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/index.ts +27 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/registry.ts +66 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/runner.ts +90 -0
- package/src/agent-src/templates/scripts/work_engine/hooks/settings.ts +260 -0
- package/src/agent-src/templates/scripts/work_engine/input_builders.ts +260 -0
- package/src/agent-src/templates/scripts/work_engine/intent/classify.ts +466 -0
- package/src/agent-src/templates/scripts/work_engine/migration/v0_to_v1.ts +531 -0
- package/src/agent-src/templates/scripts/work_engine/orchestration.ts +366 -0
- package/src/agent-src/templates/scripts/work_engine/persona_policy.ts +97 -0
- package/src/agent-src/templates/scripts/work_engine/resolvers/diff.ts +135 -0
- package/src/agent-src/templates/scripts/work_engine/resolvers/file.ts +175 -0
- package/src/agent-src/templates/scripts/work_engine/resolvers/prompt.ts +115 -0
- package/src/agent-src/templates/scripts/work_engine/scoring/confidence.ts +415 -0
- package/src/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +466 -0
- package/src/agent-src/templates/scripts/work_engine/scoring/decision_trace.ts +298 -0
- package/src/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +444 -0
- package/src/agent-src/templates/scripts/work_engine/stack/detect.ts +252 -0
- package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +745 -0
- package/src/agent-src/templates/scripts/work_engine/state.ts +1151 -0
- package/src/agent-src/templates/scripts/work_engine/state_io.ts +413 -0
- package/src/install/atomic.ts +111 -0
- package/src/install/conflict.ts +226 -0
- package/src/install/detect.ts +280 -0
- package/src/install/paths.ts +90 -0
- package/src/install/plan.ts +205 -0
- package/src/install/preflight.ts +210 -0
- package/src/install/selectedTools.ts +52 -0
- package/src/install/toolDetection.ts +120 -0
- package/src/install/txlog.ts +161 -0
- package/src/install/types.ts +175 -0
- package/src/install/wizard-plan.ts +216 -0
- package/src/scripts/prepack-check.mjs +108 -5
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `plan` step — gate + delegation to `feature-plan`.
|
|
3
|
+
*
|
|
4
|
+
* TypeScript twin of `work_engine/directives/backend/plan.py` (ADR-200
|
|
5
|
+
* py2ts Phase 1 — work_engine directive sets). Public API names stay
|
|
6
|
+
* snake_case to mirror the Python module 1:1 (per ADR-200 — Python style is
|
|
7
|
+
* part of the contract).
|
|
8
|
+
*
|
|
9
|
+
* The dispatcher cannot synthesise a plan from pure code: the real
|
|
10
|
+
* work needs code reading and judgement that only the agent has. The
|
|
11
|
+
* step therefore follows the Option-A delegation pattern described in
|
|
12
|
+
* `docs/contracts/implement-ticket-flow.md#agent-directives`:
|
|
13
|
+
*
|
|
14
|
+
* - `state.plan` empty → halt with `BLOCKED` and emit
|
|
15
|
+
* `@agent-directive: create-plan`. The orchestrator runs the
|
|
16
|
+
* `feature-plan` skill, writes its output onto `state.plan`,
|
|
17
|
+
* marks `outcomes['plan'] = 'success'`, and re-invokes the
|
|
18
|
+
* dispatcher.
|
|
19
|
+
*
|
|
20
|
+
* - `state.plan` populated with a minimally valid shape → `SUCCESS`
|
|
21
|
+
* with no mutation. Shape validation catches accidental scaffolding
|
|
22
|
+
* (e.g. an empty list, a placeholder string) that would produce a
|
|
23
|
+
* broken plan downstream.
|
|
24
|
+
*
|
|
25
|
+
* - `state.plan` populated but malformed → `BLOCKED` with numbered
|
|
26
|
+
* options so the user decides whether to re-plan, continue with the
|
|
27
|
+
* malformed plan, or abort.
|
|
28
|
+
*
|
|
29
|
+
* `analyze` is a precondition: the step refuses to plan when the
|
|
30
|
+
* upstream gate did not succeed, rather than silently re-running a
|
|
31
|
+
* derailed flow.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
import type { DeliveryState} from '../../delivery_state.js';
|
|
35
|
+
import { type Any, Outcome, StepResult, agent_directive } from '../../delivery_state.js';
|
|
36
|
+
|
|
37
|
+
/** Declared ambiguity surfaces. Every BLOCKED return maps to one code. */
|
|
38
|
+
export const AMBIGUITIES: ReadonlyArray<Record<string, string>> = [
|
|
39
|
+
{
|
|
40
|
+
code: 'upstream_analyze_failed',
|
|
41
|
+
trigger: '`analyze` outcome is not `success`',
|
|
42
|
+
resolution: 're-run `/implement-ticket` from the start',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
code: 'empty_plan_delegate',
|
|
46
|
+
trigger: '`state.plan` empty — no plan recorded yet',
|
|
47
|
+
resolution: 'agent directive `create-plan` → `/feature-plan`',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
code: 'malformed_plan',
|
|
51
|
+
trigger:
|
|
52
|
+
'plan is not a non-empty string, list of strings/dicts, ' +
|
|
53
|
+
'or dict with a non-empty `steps` list',
|
|
54
|
+
resolution: 're-run `/feature-plan` or correct the recorded plan',
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
/** Gate on `analyze`, then either delegate or validate the plan. */
|
|
59
|
+
export function run(state: DeliveryState): StepResult {
|
|
60
|
+
if (state.outcomes.analyze !== Outcome.SUCCESS) {
|
|
61
|
+
return _blocked_on_precondition(state);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (_is_plan_empty(state.plan)) {
|
|
65
|
+
return _delegate_to_feature_plan(state);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const shapeIssues = _diagnose_shape(state.plan);
|
|
69
|
+
if (shapeIssues.length > 0) {
|
|
70
|
+
return _blocked_on_shape(state, shapeIssues);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return new StepResult({ outcome: Outcome.SUCCESS });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* True when `state.plan` has nothing a downstream step could use.
|
|
78
|
+
*
|
|
79
|
+
* Whitespace-only strings count as empty — the user experience of
|
|
80
|
+
* "nothing planned" is identical to "blank placeholder", and both
|
|
81
|
+
* should delegate to `feature-plan` rather than fall through to
|
|
82
|
+
* the shape-validator.
|
|
83
|
+
*/
|
|
84
|
+
function _is_plan_empty(plan: Any): boolean {
|
|
85
|
+
if (plan === null || plan === undefined) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
if (typeof plan === 'string') {
|
|
89
|
+
return _pyStrip(plan).length === 0;
|
|
90
|
+
}
|
|
91
|
+
if (Array.isArray(plan)) {
|
|
92
|
+
return plan.length === 0;
|
|
93
|
+
}
|
|
94
|
+
if (plan instanceof Set || plan instanceof Map) {
|
|
95
|
+
return plan.size === 0;
|
|
96
|
+
}
|
|
97
|
+
if (typeof plan === 'object') {
|
|
98
|
+
return Object.keys(plan as Record<string, unknown>).length === 0;
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Return the list of shape complaints against `state.plan`.
|
|
105
|
+
*
|
|
106
|
+
* Accepted shapes (matches `report._format_plan`):
|
|
107
|
+
* a non-empty string, a list of strings or `{title, detail}` dicts,
|
|
108
|
+
* or a dict with a non-empty `steps` list. Everything else is
|
|
109
|
+
* rejected so the report renderer never has to guess.
|
|
110
|
+
*/
|
|
111
|
+
function _diagnose_shape(plan: Any): string[] {
|
|
112
|
+
const issues: string[] = [];
|
|
113
|
+
|
|
114
|
+
if (typeof plan === 'string') {
|
|
115
|
+
if (_pyStrip(plan).length === 0) {
|
|
116
|
+
issues.push('plan is a blank string');
|
|
117
|
+
}
|
|
118
|
+
return issues;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (Array.isArray(plan)) {
|
|
122
|
+
if (plan.length === 0) {
|
|
123
|
+
issues.push('plan list is empty');
|
|
124
|
+
return issues;
|
|
125
|
+
}
|
|
126
|
+
plan.forEach((item, i) => {
|
|
127
|
+
const idx = i + 1;
|
|
128
|
+
if (_isPlainObject(item)) {
|
|
129
|
+
const d = item as Record<string, unknown>;
|
|
130
|
+
if (!_pyTruthy(d.title) && !_pyTruthy(d.step)) {
|
|
131
|
+
issues.push(`plan step #${idx} has no title`);
|
|
132
|
+
}
|
|
133
|
+
} else if (typeof item !== 'string' || _pyStrip(item).length === 0) {
|
|
134
|
+
issues.push(`plan step #${idx} is not a usable string`);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
return issues;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (_isPlainObject(plan)) {
|
|
141
|
+
const steps = (plan as Record<string, unknown>).steps;
|
|
142
|
+
if (!Array.isArray(steps) || steps.length === 0) {
|
|
143
|
+
issues.push("plan dict must carry a non-empty 'steps' list");
|
|
144
|
+
}
|
|
145
|
+
return issues;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
issues.push(`plan has unsupported type: ${_pyTypeName(plan)}`);
|
|
149
|
+
return issues;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Halt with an agent directive so the orchestrator runs `feature-plan`. */
|
|
153
|
+
function _delegate_to_feature_plan(state: DeliveryState): StepResult {
|
|
154
|
+
const ticketId = _ticketId(state);
|
|
155
|
+
return new StepResult({
|
|
156
|
+
outcome: Outcome.BLOCKED,
|
|
157
|
+
questions: [
|
|
158
|
+
agent_directive('create-plan', { ticket: ticketId }),
|
|
159
|
+
`> Ticket ${ticketId} — no plan recorded yet; running ` +
|
|
160
|
+
'`feature-plan` and resuming.',
|
|
161
|
+
'> 1. Continue — use the plan produced by `feature-plan`',
|
|
162
|
+
'> 2. Abort — stop before any edits are proposed',
|
|
163
|
+
],
|
|
164
|
+
message: `Ticket ${ticketId} needs a plan before implementation.`,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function _blocked_on_precondition(state: DeliveryState): StepResult {
|
|
169
|
+
const ticketId = _ticketId(state);
|
|
170
|
+
return new StepResult({
|
|
171
|
+
outcome: Outcome.BLOCKED,
|
|
172
|
+
questions: [
|
|
173
|
+
`> Ticket ${ticketId} — plan gate refused: ` +
|
|
174
|
+
'`analyze` step did not complete successfully.',
|
|
175
|
+
'> 1. Re-run `/implement-ticket` from the start',
|
|
176
|
+
'> 2. Abort',
|
|
177
|
+
],
|
|
178
|
+
message: `Ticket ${ticketId} cannot plan: analyze gate did not pass.`,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function _blocked_on_shape(state: DeliveryState, issues: string[]): StepResult {
|
|
183
|
+
const ticketId = _ticketId(state);
|
|
184
|
+
return new StepResult({
|
|
185
|
+
outcome: Outcome.BLOCKED,
|
|
186
|
+
questions: [
|
|
187
|
+
`> Ticket ${ticketId} — recorded plan is malformed: ` + issues.join('; ') + '.',
|
|
188
|
+
'> 1. Re-run `feature-plan` and resume',
|
|
189
|
+
'> 2. Abort — the plan cannot be trusted',
|
|
190
|
+
],
|
|
191
|
+
message: `Ticket ${ticketId} plan shape invalid: ${issues.join('; ')}.`,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** `(state.ticket or {}).get("id") or "(no id)"`. */
|
|
196
|
+
function _ticketId(state: DeliveryState): string {
|
|
197
|
+
const id = (state.ticket ?? {}).id;
|
|
198
|
+
return _pyTruthy(id) ? String(id) : '(no id)';
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** Python truthiness for the scalar/container kinds these slices carry. */
|
|
202
|
+
function _pyTruthy(value: unknown): boolean {
|
|
203
|
+
if (value === null || value === undefined || value === false) {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
if (value === true) {
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
if (typeof value === 'number') {
|
|
210
|
+
return value !== 0;
|
|
211
|
+
}
|
|
212
|
+
if (typeof value === 'string') {
|
|
213
|
+
return value.length !== 0;
|
|
214
|
+
}
|
|
215
|
+
if (Array.isArray(value)) {
|
|
216
|
+
return value.length !== 0;
|
|
217
|
+
}
|
|
218
|
+
if (value instanceof Set || value instanceof Map) {
|
|
219
|
+
return value.size !== 0;
|
|
220
|
+
}
|
|
221
|
+
if (typeof value === 'object') {
|
|
222
|
+
return Object.keys(value as Record<string, unknown>).length !== 0;
|
|
223
|
+
}
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Python `str.strip()` — strip leading/trailing whitespace. */
|
|
228
|
+
function _pyStrip(s: string): string {
|
|
229
|
+
return s.trim();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** True for a dict-like value (mirrors Python `isinstance(x, dict)`). */
|
|
233
|
+
function _isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
234
|
+
return (
|
|
235
|
+
typeof value === 'object' &&
|
|
236
|
+
value !== null &&
|
|
237
|
+
!Array.isArray(value) &&
|
|
238
|
+
!(value instanceof Set) &&
|
|
239
|
+
!(value instanceof Map)
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** Python `type(x).__name__` for the value kinds the diagnose paths see. */
|
|
244
|
+
function _pyTypeName(value: unknown): string {
|
|
245
|
+
if (value === null || value === undefined) {
|
|
246
|
+
return 'NoneType';
|
|
247
|
+
}
|
|
248
|
+
if (typeof value === 'boolean') {
|
|
249
|
+
return 'bool';
|
|
250
|
+
}
|
|
251
|
+
if (typeof value === 'number') {
|
|
252
|
+
return Number.isInteger(value) ? 'int' : 'float';
|
|
253
|
+
}
|
|
254
|
+
if (typeof value === 'string') {
|
|
255
|
+
return 'str';
|
|
256
|
+
}
|
|
257
|
+
if (Array.isArray(value)) {
|
|
258
|
+
return 'list';
|
|
259
|
+
}
|
|
260
|
+
if (value instanceof Set) {
|
|
261
|
+
return 'set';
|
|
262
|
+
}
|
|
263
|
+
if (value instanceof Map || _isPlainObject(value)) {
|
|
264
|
+
return 'dict';
|
|
265
|
+
}
|
|
266
|
+
return typeof value;
|
|
267
|
+
}
|